【问题标题】:Laravel - PHPUnit multi step testingLaravel - PHPUnit 多步测试
【发布时间】:2019-06-06 07:22:19
【问题描述】:

我对单元测试的世界有点陌生。我希望我的测试尽可能清晰、干净和抽象。我有以下课程 -

class PasswordResetTest extends GraphQLTest
{

private static $user;
private $authEndpoint = '/graphql/auth';

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

    if (!self::$user instanceof User) {
        self::$user = factory(User::class)->create(
            ['password' => Hash::make('password')]
        );
    }
}

/**
 * Check our default password was set successfully
 *
 * @test
 */
public function assertDefaultPassword()
{
    // get our user
    $user = User::where('email', self::$user->email)->get();

    // check our password is 'password'
    $this->assertTrue(
        Hash::check('password', self::$user->fresh()->password),
        'Unexpected password'
    );
}

/**
 * Perform a password reset via GraphQL
 *
 * @test
 */
public function requestPasswordResetEmail()
{
    // setup our mail faker
    Mail::fake();

    // make sure nothing has been sent
    Mail::assertNothingSent();

    // set our endpoint
    $this->setGraphQLEndpoint($this->authEndpoint);
    $mutation = 'mutation forgotPassword ($email: String) {
        forgotPassword (email: $email)
    }';

    // make our request
    $result = $this->graphQLRequest($mutation, ['email' => self::$user->email]);

    // assert our response
    $result->assertJson(['data' => ['forgotPassword' => true]]);

    // check our reset was sent...
    Mail::assertSent(
        PasswordResetMail::class,
        function (PasswordResetMail $mail) use (&$reset) {
            $reset = $mail->reset;
            return $mail->hasTo(self::$user->email);
        }
    );

    return $reset;
}

/**
 * If our email was sent, now perform our reset...
 *
 * @depends requestPasswordResetEmail
 * @test
 */
public function performPasswordReset(PasswordReset $reset)
{

    // set our endpoint and create mutation
    $this->setGraphQLEndpoint($this->authEndpoint);
    $mutation = 'mutation resetPassword ($reset: inputResetPassword!) {
        resetPassword (reset: $reset)                     
    }';

    $result = $this->graphQLRequest($mutation, [
        'reset' => [
            'token' => $reset->token,
            'password' => 'newPassword',
            'password_confirmation' => 'newPassword',
        ]
    ]);

    $result->assertGraphQLNoErrors();
    $result->assertJson(['data' => ['resetPassword' => true]]);
}

所以我想在多个块中运行我的测试 -

  • 检查密码实际上是针对用户设置的
  • 请求重置密码并声明已发送电子邮件
  • 执行密码重置并声明我们的密码已更新

我可以在一种方法中运行所有这些测试,但我宁愿将它们分成单独的测试以提高可读性和可测试性,但我遇到了几个问题 -

  • setUp() 方法会针对每个测试执行,而不是针对整个测试类,所以每个测试我都有一个新用户,而不是我想要的
  • 如果我使用 DatabaseTransactions - 这是我最喜欢使用的,那么每次测试都会重置数据库,因此后续测试会失败

有什么方法可以实现我想要做的事情,还是我必须把它写成一个大测试?

谢谢!

【问题讨论】:

    标签: laravel laravel-5.7 phpunit


    【解决方案1】:

    我想出的一种可行的方法是使用@depends phpdoc

    class PasswordResetTest extends GraphQLTest
    {
    
    private static $user;
    private $authEndpoint = '/graphql/auth';
    
    /**
     * @test
     */
    public function assertDefaultPassword()
    {
    
        // create our user
        self::$user = factory(User::class)->create(
            ['password' => Hash::make('oldPassword')]
        );
    
        // check we exist on the database
        $this->assertDatabaseHas('users', ['email' => self::$user->email]);
    
        // check our password is 'password'
        $this->assertTrue(
            Hash::check('oldPassword', self::$user->password),
            'Unexpected password'
        );
    }
    
    /**
     * Perform a password reset via GraphQL
     *
     * @depends assertDefaultPassword
     * @test
     *
     * @param User $user
     *
     * @return mixed
     */
    public function requestPasswordResetEmail()
    {
        Mail::fake();
    
        // make sure nothing has been sent
        Mail::assertNothingSent();
    
        // set our endpoint
        $this->setGraphQLEndpoint($this->authEndpoint);
        $mutation = 'mutation forgotPassword ($email: String) {
            forgotPassword (email: $email)
        }';
    
        // make our request
        $result = $this->graphQLRequest($mutation, ['email' => self::$user->email]);
    
        // assert our response
        $result->assertJson(['data' => ['forgotPassword' => true]]);
    
        // check our reset was sent...
        Mail::assertSent(
            PasswordResetMail::class,
            function (PasswordResetMail $mail) use (&$reset) {
                $reset = $mail->reset;
                return $mail->hasTo(self::$user->email);
            }
        );
    
        return $reset;
    }
    
    /**
     * If our email was sent, now perform our reset...
     *
     * @depends requestPasswordResetEmail
     * @test
     */
    public function performPasswordReset(PasswordReset $reset)
    {
    
        // set our endpoint and create mutation
        $this->setGraphQLEndpoint($this->authEndpoint);
        $mutation = 'mutation resetPassword ($reset: inputResetPassword!) {
            resetPassword (reset: $reset)                     
        }';
    
        // make request to our reset
        $result = $this->graphQLRequest(
            $mutation, [
                'reset' => [
                    'token' => $reset->token,
                    'password' => 'newPassword',
                    'password_confirmation' => 'newPassword',
                ]
            ]
        );
    
        $result->assertGraphQLNoErrors();
        $result->assertJson(['data' => ['resetPassword' => true]]);
    }
    
    /**
     * After we have performed all of our tests, delete our user...
     */
    public static function tearDownAfterClass()
    {
        self::$user->forceDelete();
        parent::tearDownAfterClass();
    }
    

    }

    这样我可以在第一个测试中定义我的用户,后续测试有 @depends phpdoc 引用之前的测试,允许我在第一个请求中设置用户并在后续请求中访问用户。

    然后我使用tearDownAfterClass 方法从数据库中删除创建的用户。不过,我很想听听其他人的解决方案!

    【讨论】:

      猜你喜欢
      • 2017-11-29
      • 2016-05-21
      • 2017-10-19
      • 2020-12-09
      • 2016-06-04
      • 2018-08-09
      • 2016-07-28
      • 2016-06-04
      • 2018-05-08
      相关资源
      最近更新 更多