1

在我们的 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 之前显式检索,我每次都会得到一个新实例,因此它会起作用。

但是,它的行为完全相同:(。

我错过了什么?

4

0 回答 0