Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在测试中使用断言_Php_Laravel_Phpunit - Fatal编程技术网

Php 如何在测试中使用断言

Php 如何在测试中使用断言,php,laravel,phpunit,Php,Laravel,Phpunit,我有一个用于用户注册的API,其中包含一些您希望从常规用户注册中获得的字段 当注册成功时,api返回类似这样的响应 { "response": { "httpCode": 200, "Message": "Registration is complete." } } 但有时可能会发生电子邮件已被接收的情况,在这种情况下,将返回一条状态代码为400的适当消息 { "response": { "httpCode": 400,

我有一个用于用户注册的API,其中包含一些您希望从常规用户注册中获得的字段

当注册成功时,api返回类似这样的响应

{
    "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的测试