Php 如何在测试中使用断言
我有一个用于用户注册的API,其中包含一些您希望从常规用户注册中获得的字段 当注册成功时,api返回类似这样的响应Php 如何在测试中使用断言,php,laravel,phpunit,Php,Laravel,Phpunit,我有一个用于用户注册的API,其中包含一些您希望从常规用户注册中获得的字段 当注册成功时,api返回类似这样的响应 { "response": { "httpCode": 200, "Message": "Registration is complete." } } 但有时可能会发生电子邮件已被接收的情况,在这种情况下,将返回一条状态代码为400的适当消息 { "response": { "httpCode": 400,
{
"response": {
"httpCode": 200,
"Message": "Registration is complete."
}
}
但有时可能会发生电子邮件已被接收的情况,在这种情况下,将返回一条状态代码为400的适当消息
{
"response": {
"httpCode": 400,
"Message": "Email already taken."
}
}
现在我正在测试它,为此我编写了这个测试用例
public function testSignup()
{
$response = $this->call('POST', '/api/signup', [
'first_name' => 'abc',
'last_name' => 'xyz',
'username' => 'iamgroot',
'email' => 'hello@example.com',
]);
$response->assertStatus(200)->assertJsonStructure([
'response' => [ 'httpCode' , 'Message' ]
]);
}
在testcase中发送新电子邮件时,它通过了(以及其他测试)但是,当再次运行同一个测试时,它显然失败了,因为响应不同,但从技术角度讲,这并不是一个失败,代码按照预期工作,因此,当两种响应格式中的任何一种都存在时,我如何做这样的事情呢?它将通过,因为只需为状态代码400添加另一个断言就可以了它们。Laravel有一个名为DatabaseTransactions的特性
use Illuminate\Foundation\Testing\DatabaseTransactions;
class MyTest extends TestCase
{
use DatabaseTransactions;
public function testSignup()
{
$response = $this->call('POST', '/api/signup', [
'first_name' => 'abc',
'last_name' => 'xyz',
'username' => 'iamgroot',
'email' => 'hello@example.com',
]);
$response->assertStatus(200)->assertJsonStructure([
'response' => [ 'httpCode' , 'Message' ]
]);
}
}
此特性将使用事务,在每次测试后回滚数据。然后,您可以创建第二个测试来强制执行错误,如下所示:
public function testSignupError()
{
$email = 'test@example.com';
//create an user to take the email
factory(\App\User::class)->create(['email'=>$email]);
$response = $this->call('POST', '/api/signup', [
'first_name' => 'abc',
'last_name' => 'xyz',
'username' => 'iamgroot',
'email' => $email,
]);
$response->assertStatus(400);
}
或者,您可以避免databasetransactions特性,只需使用不同的电子邮件创建一个新方法。无论如何,在测试开始之前,请使用刷新数据库特征来清除所有数据。Laravel有一个名为DatabaseTransactions的特征
use Illuminate\Foundation\Testing\DatabaseTransactions;
class MyTest extends TestCase
{
use DatabaseTransactions;
public function testSignup()
{
$response = $this->call('POST', '/api/signup', [
'first_name' => 'abc',
'last_name' => 'xyz',
'username' => 'iamgroot',
'email' => 'hello@example.com',
]);
$response->assertStatus(200)->assertJsonStructure([
'response' => [ 'httpCode' , 'Message' ]
]);
}
}
此特性将使用事务,在每次测试后回滚数据。然后,您可以创建第二个测试来强制执行错误,如下所示:
public function testSignupError()
{
$email = 'test@example.com';
//create an user to take the email
factory(\App\User::class)->create(['email'=>$email]);
$response = $this->call('POST', '/api/signup', [
'first_name' => 'abc',
'last_name' => 'xyz',
'username' => 'iamgroot',
'email' => $email,
]);
$response->assertStatus(400);
}
或者,您可以避免databasetransactions特性,只需使用不同的电子邮件创建一个新方法。无论如何,在测试开始之前,请使用刷新数据库属性来清除所有数据。请尝试以下操作:
$this->assertThat(
$response->getStatusCode(),
$this->logicalOr(
$this->equalTo(200),
$this->equalTo(400)
)
);
$response->assertJsonStructure([
'response' => [ 'httpCode' , 'Message' ]
]);
这将首先声明响应为200或400,然后我们将声明JSON结构。请尝试以下操作:
$this->assertThat(
$response->getStatusCode(),
$this->logicalOr(
$this->equalTo(200),
$this->equalTo(400)
)
);
$response->assertJsonStructure([
'response' => [ 'httpCode' , 'Message' ]
]);
这将首先断言响应是200或400,然后我们将断言JSON结构。我从未使用过,但
数据库事务
看起来很有希望。但这两个测试中的“通过”不是相互排斥的吗;如果通过B和vv.I,我只想检查一些服务器错误/运行时错误是否不存在,如果状态为200或400(现在可以忽略json结构),它应该通过否,因为这是预期的行为。如果你想让你的服务器给出200或400的响应,那没关系,测试应该通过,如果这是你想要的。哦…很酷,那么我刚刚开始测试,从未使用过工厂,这就是为什么我对实现这一点感到困惑,所以我也需要使用刷新数据库
?是的。在运行测试之前,需要刷新数据库来清理数据库,并确保您知道哪些数据是您从未使用过的,但DatabaseTransactions
看起来很有希望。但这两个测试的“通过”不是相互排斥的吗;如果通过B和vv.I,我只想检查一些服务器错误/运行时错误是否不存在,如果状态为200或400(现在可以忽略json结构),它应该通过否,因为这是预期的行为。如果你想让你的服务器给出200或400的响应,那没关系,测试应该通过,如果这是你想要的。哦…很酷,那么我刚刚开始测试,从未使用过工厂,这就是为什么我对实现这一点感到困惑,所以我也需要使用刷新数据库
?是的。RefreshDatabase需要在运行测试之前清理您的数据库,并确保您知道响应中包含哪些数据,它给了我一些想法,但$response->assertStatus($response->getStatusCode())
将通过所有状态代码,如500404等,但我只想通过200和400的测试谢谢您的响应,它给了我一些想法,但$response->assertStatus($response->getStatusCode())
将通过所有状态代码,如500404等,但我只想通过200和400的测试