为Laravel测试在数据库中播种和删除数据的正确方法?

时间:2018-12-23 07:37:39

标签: php laravel phpunit

我是Laravel测试的新手,我目前正在构建测试,因此它们使用数据库中的某些数据来检查HTTP请求是否做了适当的工作。 我试图弄清楚如何在运行测试之前将数据“种子”到数据库中,并且在所有测试完成后也删除该数据(无论成功还是失败,都应该删除)。

我试图了解如何正确地阅读互联网上的一些文章,但是找不到适合我的解决方案。

我知道在node.js中,Mocha测试在每次测试之前都有一个“ beforeEach”来操纵数据,PHP Laravel中是否有类似的选择?

2 个答案:

答案 0 :(得分:1)

当laravel版本大于5.5时,您可以在测试中使用RefreshDatabase特性,它将在运行测试后重置数据库。您所要做的就是像在下面那样将其添加到测试的顶部

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;

class YourModelNameTest extends TestCase
{
    use RefreshDatabase;


    public function setUp()
    {
        parent::setUp();

        // This will run all your migration
        Artisan::call('migrate');

        // This will seed your database
        Artisan::call('db:seed');

        // If you wan to seed a specific table
        Artisan::call('db:seed', ['--class' => 'TableNameSeeder ', '--database' => 'testing']);
    }

}

RefreshDatabase特性定义了refreshDatabase,它们在每次测试之前和之后都迁移数据库。您可以在此处查看代码

RefreshDatabse refreshDatabase

答案 1 :(得分:0)

虽然Yves的答案应该可以工作(单独的数据库),但我发现了一组方法可以帮助实现我所需要的: “ setUp”和“ tearDown”。

在运行所有测试集(测试类)之前,“ setUp”方法将执行某些操作,而在所有这些测试执行之后,“ tearDown”将执行某些操作。

我在这里附上我的测试类,以作为我如何使用它们的示例:

<?php

namespace Tests\Feature;

use App\User;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class UserTest extends TestCase
{
    private $token;

    public function setUp(){
        parent::setUp();

        $userData = [
            'email' => 'mytestemail@email.com',
            'password' => '123456'
        ];

        $response = json_decode($this->post('/register', $userData)->baseResponse->getContent());

        $this->token = $response->token;
    }
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testRegister()
    {
        $validData = [
            'email' => 'testrerere@email.com',
            'password' => '123456'
        ];

        $invalidEmail = [
            'email' => 'not_a_real_email',
            'password' => '123456'
        ];

        $invalidPassword = [
            'email' => 'test2@email.com',
            'password' => '12'
        ];

        $emptyData = [];

        $goodResponse = $this->post('/register', $validData);

        $goodResponse->assertStatus(201);
        $goodResponse->assertJsonStructure(['token']);

        User::where('email', 'testrerere@email.com')->delete();

        $invalidEmailResponse = $this->post('/register', $invalidEmail);
        $invalidEmailResponse->assertStatus(400);

        $invalidPasswordResponse = $this->post('/register', $invalidPassword);
        $invalidPasswordResponse->assertStatus(400);

        $emptyDataResponse = $this->post('/register', $emptyData);
        $emptyDataResponse->assertStatus(400);
    }

    public function testToken()
    {
        $validData = [
            'email' => 'mytestemail@email.com',
            'password' => '123456'
        ];

        $invalidData = [
            'email' => 'nonexistingemail@test.com',
            'password' => '123456'
        ];

        $validDataResponse = $this->post('/token', $validData);
        $validDataResponse->assertStatus(200);
        $validDataResponse->assertJsonStructure(['token']);

        $invalidDataResponse = $this->post('/token', $invalidData);
        $invalidDataResponse->assertStatus(400);
    }

    //get an account object based on a token
    public function testAccount()
    {
        $goodResponse = $this->withHeaders([
            'Authorization' => 'Bearer ' . $this->token,
        ])->json('GET', '/account');

        $goodResponse
            ->assertStatus(200)
            ->assertJsonStructure([
                'user',
            ]);

        //altering the token to get an invalid token error
        $badResponse = $this->withHeaders([
            'Authorization' => 'Bearer L' . $this->token,
        ])->json('GET', '/account');

//        print_r($badResponse->baseResponse->getContent());

        $badResponse->assertJson(['status' => 'Token is Invalid']);
    }

    public function tearDown()
    {
        User::where('email', 'mytestemail@email.com')->delete();
        User::where('email', 'testrerere@email.com')->delete();

        parent::tearDown();
    }
}