在我们的 Symfony 应用程序中,我们有处理身份验证的自定义代码。它基于phpleague/oauth2-server之上。
我们有 2 种类型的身份验证,最终都调用TokenStorage::setToken()
.
这一切都完美无缺。
现在我们决定在我们的包中添加一些 Behat 测试:
Scenario: I am able to login with type 1
When I login with type 1
Then I am successfully logged in as a "type1" member
Scenario: I am able to login with type 2
When I login with type 2
Then I am successfully logged in as a "type2" member
(为了不暴露特定业务的术语,我更改了场景的实际措辞)
为了测试这些Then
步骤,我需要访问TokenStorage
我的上下文中的 ,因为我基本上想测试用户是否具有正确的安全角色:
default:
gherkin:
cache: null
suites:
mybundle:
paths: [ %paths.base%/src/My/Bundle/Features ]
contexts:
- My\Bundle\Context\LoginContext
tokenStorage: '@security.token_storage'
extensions:
Behat\Symfony2Extension:
kernel:
env: "test"
debug: "true"
我的上下文如下所示:
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Behat\Behat\Context\Context;
class LoginContext implements Context
{
private $tokenStorage;
public function __construct(TokenStorage $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
/**
* @Then I am successfully logged in as a :expectedRole member
*/
public function iAmSuccessfullyLoggedInAsAMember($expectedRole)
{
$found = false;
foreach ($this->tokenStorage->getToken()->getRoles() as $role) {
if ($role->getRole() == $expectedRole) {
$found = true;
break;
}
}
if (! $found) {
throw new \Exception('Incorrect role');
}
}
}
会发生什么:
- 如果我只运行第一个场景,它可以正常工作
- 如果我只运行第二个场景,它可以正常工作
- 如果我同时运行它们,那么在第二种情况下我会收到错误
Call to a member function getRoles() on a non-object
为什么会这样?我怎样才能让它正常工作?
我的版本是:
- 行为/行为:3.1.0
- 贝哈特/小黄瓜:4.4.1
- behat/symfony2-扩展:2.1.1
- symfony/symfony:2.6.13
我尝试的一种解决方案是让我的上下文实现Behat\Symfony2Extension\Context\KernelAwareContext
接口,然后我这样做:
use Behat\Symfony2Extension\Context\KernelAwareContext;
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
class LoginContext implements KernelAwareContext
{
private $tokenStorage;
private $kernel;
public function setKernel(KernelInterface $kernel)
{
$this->kernel = $kernel;
}
/**
* @BeforeScenario
*/
public function getDependencies(BeforeScenarioScope $scope)
{
$container = $this->kernel->getContainer();
$this->tokenStorage = $container->get('security.token_storage');
}
}
我的想法是,通过在每个场景TokenStorage
之前显式检索,我每次都会得到一个新实例,因此它会起作用。
但是,它的行为完全相同:(。
我错过了什么?