为什么TokenStorage在Behat场景之间的行为不正确?

时间:2016-07-04 08:23:45

标签: symfony oauth behat symfony-2.6 symfony-security

在我们的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 / behat :3.1.0
  • behat / gherkin :4.4.1
  • behat / symfony2-extension :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 ,我每次都会得到一个新的实例,因此它会起作用。

然而,它表现完全相同:(。

我错过了什么?

0 个答案:

没有答案