Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Behat验证Symfony2用户_Symfony_Behat - Fatal编程技术网

Behat验证Symfony2用户

Behat验证Symfony2用户,symfony,behat,Symfony,Behat,我正在Symfony2/Doctrine2中使用Behat。现在,我有一个场景可以归结为这样一个事实:“如果我登录并转到/login,我应该转到/而不是”: 对于@login,我创建了以下内容: /** * @BeforeScenario @login */ public function loginUser() { $doctrine = $this->getContainer()->get('doctrine'); $userRepository = $doc

我正在Symfony2/Doctrine2中使用Behat。现在,我有一个场景可以归结为这样一个事实:“如果我登录并转到/login,我应该转到/而不是”:

对于@login,我创建了以下内容:

/**
 * @BeforeScenario @login
 */
public function loginUser()
{
    $doctrine = $this->getContainer()->get('doctrine');
    $userRepository = $doctrine->getRepository('MyTestBundle:User');
    $user = $userRepository->find(1); // 1 = id

    $token = new UsernamePasswordToken($user, NULL, 'main', $user->getRoles());
    $this->getContainer()->get('security.context')->setToken($token);
}
在“when I go to/login”(当我进入/登录)代码中(调用控制器),令牌似乎不见了(不是我想要的):

但在FeatureContext中,它似乎一直存在(我希望它能以这种方式工作)。在“给定我已登录”中:

我的跑步行为如下:

app/console -e=test behat
我也在控制器中进行了此操作,以确保其处于测试状态:

fwrite($fd, $this->get('kernel')->getEnvironment());
// prints 'test'
有关于如何验证用户身份的线索吗?我将不得不测试许多管理页面,因此如果我能将登录链接到@BeforeSuite、@beforefeact(或@beforescapture…)中就好了,这样我就不会被阻止


(关于禁用测试的身份验证机制或存根/模拟用户的方法的建议也很受欢迎。)

哦,我的天。它不起作用,因为FeatureContext中的DIC没有与应用程序共享-应用程序有单独的内核和DIC。你可以通过水貂得到它。或者,您可以简单地以正确的方式执行:-)

正确的方式意味着,最终用户可以观察到的行为的每个部分都应该在*.feature中描述,而不是在FeatureContext中描述。这意味着,如果你想登录一个用户,你应该简单地描述它的步骤(如:“我在/登录”,“我填写用户名…”,“我填写密码”和stuf)。如果您想多次执行,您应该创建一个元步骤


元步骤是简单的步骤,描述了多个其他步骤,例如“我以everzet的身份登录”。您可以在这里了解它们:

这是我使用的OAuth登录解决方案。在多次搜索答案并登陆此页面后,我认为分享解决方案将是非常棒的。希望它能帮助别人

后台:使用HWIOAuthBundle的Symfony2应用程序,连接到某些OAuth2提供商

问题:当Behat上下文未与Symfony上下文共享时,如果我已登录,如何实现

解决方案

HWIOAuthBundle使用
@buzz
服务对OAuth提供程序进行所有API调用。因此,您所需要做的就是将Buzz客户端替换为您的实现,该实现不调用外部服务,但会立即返回结果。这是我的实现:

<?php

namespace Acme\ExampleBundle\Mocks;

use Buzz\Client\ClientInterface;
use Buzz\Message\MessageInterface;
use Buzz\Message\RequestInterface;

class HttpClientMock implements ClientInterface
{
    public function setVerifyPeer()
    {
        return $this;
    }

    public function setTimeout()
    {
        return $this;
    }

    public function setMaxRedirects()
    {
        return $this;
    }

    public function setIgnoreErrors()
    {
        return $this;
    }

    public function send(RequestInterface $request, MessageInterface $response)
    {
        if(preg_match('/\/oauth2\/token/', $request->getResource()))
        {
            $response->setContent(json_encode([
                'access_token' => 'valid',
                'token_type' => 'bearer',
                'expires_in' => 3600
            ]));
        }
        elseif(preg_match('/\/oauth2\/me/', $request->getResource()))
        {
            $response->setContent(json_encode([
                'id' => 1,
                'username' => 'doctor',
                'realname' => 'Doctor Who'
            ]));
        }
        else throw new \Exception('This Mock object doesn\'t support this resource');
    }
}
<?php
/**
 * @Given /^I\'m logged in$/
 */
public function iMLoggedIn()
{
    $this->getSession()->visit($this->locatePath('/login/check-yourOauthProvider?code=validCode'));
}
最后,您需要为测试环境将
require\u previous\u session
设置为false,因此我建议将其作为参数传递

# app/config/security.yml
security:
    firewalls:
        secured_area:
            oauth:
                require_previous_session: false
现在,您可以像这样实现您的步骤

规格:

Feature: Access restricted resource

  Scenario: Access restricted resource
    Given I'm logged in
    When I go to "/secured-area"
    Then I should be on "/secured-area"
    And the response status code should be 200
实施:

<?php

namespace Acme\ExampleBundle\Mocks;

use Buzz\Client\ClientInterface;
use Buzz\Message\MessageInterface;
use Buzz\Message\RequestInterface;

class HttpClientMock implements ClientInterface
{
    public function setVerifyPeer()
    {
        return $this;
    }

    public function setTimeout()
    {
        return $this;
    }

    public function setMaxRedirects()
    {
        return $this;
    }

    public function setIgnoreErrors()
    {
        return $this;
    }

    public function send(RequestInterface $request, MessageInterface $response)
    {
        if(preg_match('/\/oauth2\/token/', $request->getResource()))
        {
            $response->setContent(json_encode([
                'access_token' => 'valid',
                'token_type' => 'bearer',
                'expires_in' => 3600
            ]));
        }
        elseif(preg_match('/\/oauth2\/me/', $request->getResource()))
        {
            $response->setContent(json_encode([
                'id' => 1,
                'username' => 'doctor',
                'realname' => 'Doctor Who'
            ]));
        }
        else throw new \Exception('This Mock object doesn\'t support this resource');
    }
}
<?php
/**
 * @Given /^I\'m logged in$/
 */
public function iMLoggedIn()
{
    $this->getSession()->visit($this->locatePath('/login/check-yourOauthProvider?code=validCode'));
}

可以在这里调用UI层的“内部”层(在symfony中:与模型对话)。
对于所有的symfony用户,behat建议使用带有tables参数的给定步骤来设置记录,而不是fixture。通过这种方式,您可以在一个位置读取所有场景,并且无需在文件之间跳转即可理解其中的含义:

如果有用户:
|用户名|密码|电子邮件|
|埃弗泽特| 123456 |everzet@knplabs.com|

|法布特|22@222 | fabpot@symfony.com|

是一篇简单明了的文章,介绍如何创建登录会话并设置貂会话cookie,以便貂会话登录。这比每次使用登录表单登录用户要好得多。

确实好得多(而且更简单)。我只是把这些修改推到了我的项目中。谢谢如果与oAuth讨论授权,该怎么办?我只需要在功能上下文中对用户进行身份验证,只需将其标记为登录,而无需任何附加步骤,因为在这种情况下,它不会帮助您提到可以获取应用程序的内核和DIC,你会怎么做?仅仅因为用户必须使用登录页面来访问某个区域并不意味着所有的测试都应该使用登录表单。通过这样做,您现在将每个测试场景耦合到登录表单。在许多应用程序中,还有“记住我”功能和电子邮件链接登录(电子邮件验证、忘记密码等)。仅仅因为它被称为行为驱动开发并不意味着最终用户的行为。它意味着所有角色、用户、业务组等的预期系统行为。
Feature: Access restricted resource

  Scenario: Access restricted resource
    Given I'm logged in
    When I go to "/secured-area"
    Then I should be on "/secured-area"
    And the response status code should be 200
<?php
/**
 * @Given /^I\'m logged in$/
 */
public function iMLoggedIn()
{
    $this->getSession()->visit($this->locatePath('/login/check-yourOauthProvider?code=validCode'));
}