Symfony FOSUserBundle单元测试

Symfony FOSUserBundle单元测试,symfony,fosuserbundle,Symfony,Fosuserbundle,我正在与fosUserBundle建立一个网站。我需要编写一些单元测试,但我似乎无法使身份验证正确地用于它们。我尝试过几种方法,但都没有成功 Approach 1-在安全设置中链接提供程序,以进行我可以依赖的标准登录。当我这样做时,唯一有效的身份验证是内存提供程序,这意味着我可以使用管理员用户登录,但不能使用fosUserBundle创建的任何用户 security.yml security: encoders: "FOS\UserBundle\Model\UserInt

我正在与fosUserBundle建立一个网站。我需要编写一些单元测试,但我似乎无法使身份验证正确地用于它们。我尝试过几种方法,但都没有成功

Approach 1-在安全设置中链接提供程序,以进行我可以依赖的标准登录。当我这样做时,唯一有效的身份验证是内存提供程序,这意味着我可以使用管理员用户登录,但不能使用fosUserBundle创建的任何用户

security.yml

security: encoders: "FOS\UserBundle\Model\UserInterface": plaintext "Symfony\Component\Security\Core\User\User": plaintext providers: chain_provider: providers: [in_memory, fos_userbundle] in_memory: users: admin: { password: admin, roles: [ 'ROLE_ADMIN' ] } fos_userbundle: id: fos_user.user_manager firewalls: main: pattern: ^/ form_login: provider: fos_userbundle login_path: / csrf_provider: form.csrf_provider default_target_path: /media logout: true anonymous: true http_basic: provider: in_memory 安全: 编码器: “FOS\UserBundle\Model\UserInterface”:纯文本 “Symfony\Component\Security\Core\User\User”:纯文本 供应商: 供应链供应商: 提供者:[内存中,fos\u用户包] 内存中: 用户: 管理员:{密码:管理员,角色:['ROLE_admin']} fos_用户包: id:fos\U用户。用户\U经理 防火墙: 主要内容: 模式:^/ 表格(u)登入: 提供商:fos_用户包 登录路径:/ csrf\u提供程序:form.csrf\u提供程序 默认\u目标\u路径:/media 注销:正确 匿名:是的 http_basic: 提供者:内存中 方法2-我在单元测试设置中创建了一个用户。但是使用这种方法,我永远无法使用我刚刚创建的用户登录,我不需要用户确认

public function setUp() { $kernel = static::createKernel(); $this->repo = $kernel->boot(); $this->repo = $kernel->getContainer(); $userManager = $this->repo->get('fos_user.user_manager'); $email = "testing".(string) self::newRandomNumber()."@test.com"; $un = "test".(string) self::newRandomNumber(); $fn = "testin"; $ln = "laster"; $pwd = "passworD1"; $user = $userManager->createUser(); $user->setEmail($email); $user->setUsername($un); $user->setFirstName($fn); $user->setLastName($ln); $user->setPlainPassword($pwd); $user->setBimStaff(True); // Persist the user to the database $userManager->updateUser($user); $this->user = $user; $this->client = static::createClient(); $crawler = $this->client->request('GET', '/'); $form = $crawler->selectButton('Login')->form(); // set some values $un = 'Lucas'.self::newRandomNumber(); $form['_username'] = $un; $form['_password'] = $pwd; // submit the form $crawler = $this->client->submit($form); print_r($this->client->getResponse()); $this->client->followRedirects(); } 公共功能设置(){ $kernel=static::createKernel(); $this->repo=$kernel->boot(); $this->repo=$kernel->getContainer(); $userManager=$this->repo->get('fos_user.user_manager'); $email=“testing”。(字符串)self::newRandomNumber()。“@test.com”; $un=“test”。(字符串)self::newRandomNumber(); $fn=“testin”; $ln=“laster”; $pwd=“passworD1”; $user=$userManager->createUser(); $user->setEmail($email); $user->setUsername($un); $user->setFirstName($fn); $user->setLastName($ln); $user->setPlainPassword($pwd); $user->setBimStaff(True); //将用户持久化到数据库 $userManager->updateUser($user); $this->user=$user; $this->client=static::createClient(); $crawler=$this->client->request('GET','/'); $form=$crawler->selectButton('Login')->form(); //设定一些值 $un='Lucas'.self::newRandomNumber(); $form[''u username']=$un; $form[''u password']=$pwd; //提交表格 $crawler=$this->client->submit($form); 打印($this->client->getResponse()); $this->client->followRedirects(); } 我尝试了在表单上登录和http基本身份验证,但两者都不起作用

有人有什么建议吗

谢谢,
Cory

嗯,似乎如果你在安全性中链接提供者,你不能只使用其中一个提供者,至少这解决了我的问题

//security.yml
供应商:
供应链供应商:
提供者:[内存中,fos\u用户包]
内存中:
用户:
管理员:{密码:管理员,角色:['ROLE_admin']}
fos_用户包:
id:fos\U用户。用户\U经理
防火墙:
主要内容:
模式:^/
表格(u)登入:
提供者:连锁店提供者
登录路径:/
csrf\u提供程序:form.csrf\u提供程序
默认\u目标\u路径:/media
注销:正确
匿名:是的
http_basic:
提供者:连锁店提供者
出于某种原因,当我将两个提供者都更改为
chain\u provider
时,它就开始合作了

我的单元测试现在看起来像这样

公共功能设置(){
$kernel=static::createKernel();
$this->repo=$kernel->boot();
$this->repo=$kernel->getContainer();
$this->client=static::createClient(数组(),数组(
'PHP_AUTH_USER'=>'admin',
'PHP_AUTH_PW'=>'admin',
));
$this->client->followRedirects();
}


如果复制此选项,我建议为您的用户使用更强大的密码:)

我也有同样的问题,但我希望选项2能够工作。你的榜样就在那里,对我很有帮助。我认为它不适用于您的原因是用户未启用。默认情况下,FOSUserBundle中的用户构造函数将创建禁用的用户,因此您必须调用
$user->setEnable(true)

这是我的工作示例

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;

class MyControllerTest extends WebTestCase
{
    private $client = null;

    public function setUp()
    {
        $this->client = static::createClient();
    }

    private function logIn()
    {
        $session = $this->client->getContainer()->get('session');

        $userManager = $this->client->getContainer()->get('fos_user.user_manager');

        $user=$userManager->findUserByUsername('tester');
        if (!$user) {
            $user = $userManager->createUser();

            $user->setEmail('test@example.com');
            $user->setUsername('tester');
            $user->setPlainPassword('foo');
            $user->setEnabled(true);
            $user->addRole('ROLE_SUPER_ADMIN');

            $userManager->updateUser($user);
        }

        $firewall = 'main_firewall';
        $token = new UsernamePasswordToken($user, null, $firewall, array('ROLE_SUPER_ADMIN'));

        $session->set('_security_'.$firewall, serialize($token));
        $session->save();

        $cookie = new Cookie($session->getName(), $session->getId());
        $this->client->getCookieJar()->set($cookie);
    }

    public function testCompleteScenario()
    {
        $this->logIn();

        $crawler = $this->client->request('GET', '/foo/');
        $this->assertEquals(200, $this->client->getResponse()->getStatusCode(),
            "Unexpected HTTP status code for GET /foo/".$this->client->getResponse()->getContent());

    }

}

另一方面:它是功能测试,当您测试一个涉及整个堆栈的特性时,单元测试是测试一个与其他类隔离的类。我建议您在测试期间使用(和)将数据加载到数据库中。您不需要在测试函数中定义实体。