在我们的Symfony应用程序中,我们有自定义代码来处理身份验证。它基于thephpleague/oauth2-server的顶部。
我们有两种类型的身份验证,最终都会调用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
为什么会这样?如何使其正常工作?
我的版本是:
我尝试的一个解决方案是让我的上下文实现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
,我每次都会得到一个新的实例,因此它会起作用。
然而,它表现完全相同:(。
我错过了什么?