我是单元测试领域的新手。我希望我的测试尽可能清晰,干净和抽象。我有以下课程-
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
-这是我理想的用法,那也会在每次测试时重置数据库,因此后续测试将失败有什么方法可以实现我想做的事情,还是必须将其编写为一项大测试?
谢谢!
答案 0 :(得分:0)
一种可行的方法是使用@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
方法从数据库中删除了创建的用户。我还是很想听听其他人的解决方案!