4.测试 Eloquent 模型

未匹配的标注

本系列文章为laracasts.com 的系列视频教程——Testing Laravel 的学习笔记。若喜欢该系列视频,可去该网站订阅后下载该系列视频,支持正版

本节说明

  • 对应第 4 小节:Testing Eloquent Models

本节内容

本节我们来学习测试 Laravel 的Model。首先我们进行配置phpunit.xml文件:

phpunit.xml

    .
    .
    .
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="DB_CONNECTION" value="sqlite"/>
        <env name="DB_DATABASE" value=":memory:"/>
        <env name="BCRYPT_ROUNDS" value="4"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="QUEUE_CONNECTION" value="sync"/>
        <env name="MAIL_DRIVER" value="array"/>
    </php>
</phpunit>

我们在内存中进行测试,这样测试运行的速度会快一些,所以在 database 配置项中我们将使用 sqlite:memory:选项(Sqlite的内存数据库)。

接下来我们建立Article模型和数据库迁移文件:

$ php artisan make:model Article -m

修改迁移文件:

database\migrations{timestamp}_create_articles_table.php

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateArticlesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->integer('reads')->default(0);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('articles');
    }
}

为了简单起见,我们仅定义了两个字段:titlereads,即标题与阅读次数。然后我们新建测试:

$ php artisan make:test ArticleTest --unit

建立模型工厂:

database\factories\ArticleFactory.php

<?php

use Faker\Generator as Faker;

/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/

$factory->define(App\Article::class, function (Faker $faker) {
    return [
        'title' => $faker->sentence,
    ];
});

现在我们来建立我们的第一个测试,对于我们的测试而言,我们的测试逻辑如下:

tests\Unit\ArticleTest.php

/** @test */
public function it_fetches_trending_articles()
{
    // Given
    // When
    // Then
}

假设我们有一些数据,当我们执行了动作之后,我们需要验证什么。我们按照这个思路来编写测试:

<?php

use App\Article;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;

class ArticleTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function it_fetches_trending_articles()
    {
        factory('App\Article',2)->create();
        factory('App\Article')->create(['reads' => 10]);
        $mostPopular = factory('App\Article')->create(['reads' => 20]);

        $articles = Article::trending();

        $this->assertEquals($mostPopular->id,$articles->first()->id);
        $this->assertCount(3,$articles);
    }
}

现在我们可以来运行测试了:
file

我们利用 本地作用域 来获取最流行的 3 篇文章:

app\Article.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    public function scopeTrending($query,$take = 3)
    {
        return $query->orderBy('reads','desc')->take($take)->get();
    }
}

再次测试:
file

现在我们已经学习了测试model的一个小例子,正如这个例子而言,测试的内容单一:仅测试了能够获取流行的 3 篇文章,仅此而已。但是这样是必要的,因为你可以准确地通过你的测试定位到测试失败的位置。请记住,不要企图在一个测试中测试很多、很复杂的东西,那样会得不偿失。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~