Php 为Laravel测试在数据库中播种和删除数据的正确方法?
我是Laravel测试的新手,我目前正在构建我的测试,以便他们使用我数据库中的某些数据来检查HTTP请求是否完成了相应的工作。 我试图弄清楚如何在运行测试之前将数据“种子”到数据库中,但在所有测试完成后也删除这些数据(成功或失败,无论如何都应该删除) 通过阅读互联网上的一些文章,我试图理解如何正确地做到这一点,但就是找不到适合我的解决方案Php 为Laravel测试在数据库中播种和删除数据的正确方法?,php,laravel,phpunit,Php,Laravel,Phpunit,我是Laravel测试的新手,我目前正在构建我的测试,以便他们使用我数据库中的某些数据来检查HTTP请求是否完成了相应的工作。 我试图弄清楚如何在运行测试之前将数据“种子”到数据库中,但在所有测试完成后也删除这些数据(成功或失败,无论如何都应该删除) 通过阅读互联网上的一些文章,我试图理解如何正确地做到这一点,但就是找不到适合我的解决方案 我知道在node.js中,Mocha测试有一个“beforeach”来在每次测试之前操作数据,PHP Laravel中是否有类似的选项?如果Laravel版本
我知道在node.js中,Mocha测试有一个“beforeach”来在每次测试之前操作数据,PHP Laravel中是否有类似的选项?如果Laravel版本大于5.5,您可以在测试中使用
刷新数据库
特性,该特性将在测试运行后重置数据库。你所要做的就是将它添加到测试的顶部,如下面所示
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
,用于在每次测试前后迁移数据库。你可以在这里看到代码
虽然Yves answer应该可以工作(单独的数据库),但我发现了一套方法可以帮助实现我所需要的: “设置”和“拆卸” “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();
}
}
你能再详细一点吗?这实际上是如何服务于我在这个问题中的请求的目的的?这只是帮助在运行测试后恢复数据库的状态,我修改了答案,在测试之前添加了其他部分来种子数据库。我刚刚尝试了它,它删除了数据库中的所有数据,不好。你应该有两个数据库,一个用于测试,另一个用于生产,但不在真实数据上运行测试,请在测试数据库上使用假数据。指定测试数据库加载项phpunit.xml
文件