【问题标题】:Correct way to seed and delete data in the database for Laravel testing?为 Laravel 测试在数据库中播种和删除数据的正确方法?
【发布时间】:2019-05-22 22:35:31
【问题描述】:

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

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

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

【问题讨论】:

    标签: php laravel phpunit


    【解决方案1】:

    对于大于 5.5 的 laravel 版本,您可以在测试中使用 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 trait 定义了 refreshDatabase,它在每次测试之前和之后迁移数据库。你可以在这里看到代码

    RefreshDatabse refreshDatabase

    【讨论】:

    • 你能详细说明一下吗?这实际上如何满足我在这个问题中请求的目的?
    • 这只是帮助您在运行测试后恢复数据库的状态,我修改答案以添加其他部分以在测试前为数据库播种
    • 我刚试了一下,它删除了我在数据库中的全部数据,不好。
    • 你应该有两个数据库,一个用于测试,另一个用于生产,而不是对真实数据进行测试,在你的测试数据库上使用假数据。指定测试数据库添加phpunit.xml文件<env name="DB_DATABASE" value="test_database_name"/>
    【解决方案2】:

    虽然 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();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-10
      • 2014-03-20
      • 1970-01-01
      • 2015-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多