如何解决在每个测试在功能测试中无法通过身份验证之前重置数据库
我正在为我的REST-Api进行功能测试。 Api受授权保护。为此,我选择了json_login提供程序。到现在为止还挺好。在正常环境中通过失眠进行访问时,身份验证才有效。
现在我需要功能测试。为此,我通过配置的User-class创建一个用户并将其保留在数据库中。可以正常工作。 但是当然,该测试仅能运行一次,因为用户已经在以下测试中存在。
因此,我尝试了hautelook/alice-bundle
的ResetDatabaseTrait或ReloadDatabaseTrait以及dmaicher/doctrine-test-bundle
。
两者都表现出相同的行为:身份验证器找不到新创建的用户。 (EntityUserProvider::loadUserByUsername
未找到用户)
很显然,EntityUserProvider似乎在数据库中使用了不同的“连接”,无法查看那些库启动的事务。
在我的测试中,负责持久保存用户的实体管理器是通过以下方式创建的:
protected function setUp(): void {
$kernel = self::bootKernel();
$this->em = $kernel->getContainer()
->get('doctrine')
->getManager();
}
或直接在创建用户之前
$em = self::$container->get('doctrine')->getManager();
这对我来说似乎是正确的。但是无论如何,我都会得到相同的结果->“无效的凭据”,因为找不到用户。
也许有人可以指出我正确的方向?
解决方法
休息片刻后,我记得创建测试时的一个细节。所有示例都不需要其中带有self:bootKernel()的setUp-Method。但是没有它,self::$container
属性为空,因此我将其添加到测试类中。也许有解决问题的方法?
我是对的!
我正在使用Api-Platform
软件包。因此,我的测试班基于ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase
。该类没有setUp方法,但是检查createClient()
时发现,通过调用bootKernel()
创建了内核,该内核也停止了所有正在运行的内核。
所以我的setUp()方法创建了一个内核。使用该内核,我创建了我的用户。
然后,我致电createClient()
为请求创建测试客户端。这杀死了我最初的内核,并创建了一个新内核,然后导致了问题。
重新排列语句-首先创建客户端,然后从现在创建的容器中获取EntityManager,并在创建客户端解决问题后创建User。
,两天后,呵呵
当你想调用多个请求时,例如,如果你想要第一个请求你得到令牌,第二个你用这个令牌调用并检查身份验证,在这个调用中,如果你使用 use Hautelook\AliceBundle\PhpUnit\RefreshDatabaseTrait
trait 你的数据库第一次调用后休息,您有令牌但数据库为空,第二次调用失败。
因此,请再次阅读文档的这一重要部分:
但是有一个警告:在某些测试中,有必要在一个测试中执行多个请求,例如当通过 API 创建用户并检查使用相同密码进行后续登录时。但是,默认情况下客户端将重新启动内核,这将重置数据库。您可以通过添加 $client->disableReboot(); 来防止这种情况发生。到这样的测试。 Writing Functional Tests
我知道我们是懒惰的开发人员,而且首先阅读的是代码,而不是文档 :-)
$client = static::createClient();
$client->disableReboot();
$manager = self::getContainer()->get('doctrine')->getManager();
$user = new User();
$user->setEmail('user@example.com');
$user->setPassword(
self::getContainer()->get('security.user_password_hasher')->hashPassword($user,$password = 'pass1234')
);
$manager->persist($user);
$manager->flush();
$response = $client->request('POST','/authentication-token',[
'headers' => ['Content-Type' => 'application/json'],'json' => [
'email' => $user->getEmail(),'password' => $password,],]);
$token = $response->toArray()['token'] ?? null;
$client->request('GET','/profile',[
'auth_bearer' => $token
]);
self::assertResponseIsSuccessful();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。