2013-02-16 4 views
1

Я пишу модульные тесты для своего приложения Symfony 2, которое использует FOSUserBundle. В отличие от этого аналогичного вопроса: FOSUserBundle Unit testingUnit Testing и FOSUserBundle

Однако, я не использую HTTP-аутентификацию (только форма входа), и мне нужно использовать фактические пользовательские объекты, не поддельные в памяти.

Несмотря на множество поисков и попыток, я просто не могу заставить его работать, и весь процесс настолько непрозрачен, что я даже не знаю с чего начать. Вот код, который у меня есть:

protected $em; 
protected $client; 
protected $testuser; 

public function setUp() { 
    $kernel = static::createKernel(); 
    $kernel->boot(); 
    $this->em = $kernel->getContainer()->get('doctrine.orm.entity_manager'); 
    $this->em->beginTransaction(); 

    $this->client = static::createClient(); 

    $usermanager = $kernel->getContainer()->get('fos_user.user_manager'); 
    $this->testuser = $usermanager->createUser(); 
    $this->testuser->setUsername('test'); 
    $this->testuser->setEmail('[email protected]'); 
    $this->testuser->setPlainPassword('test'); 
    $usermanager->updateUser($this->testuser); 
} 


public function testLogin() { 
    $crawler = $this->client->request('GET', '/en/login'); 
    $form = $crawler->selectButton('_submit')->form(array(
     '_username' => 'test', 
     '_password' => 'test', 
     ));  
    $this->client->submit($form); 

    $this->assertTrue($this->client->getResponse()->isRedirect(), 'should be redirected'); 
    $this->assertTrue($this->client->getResponse()->isRedirect('http://localhost/en/account'), 'should be redirected to account page'); 

    $crawler = $this->client->followRedirect(); 

и он не работает по второму утверждению. Насколько я могу понять, он перенаправляет обратно на страницу входа.

Я застрял, и я даже не знаю, с чего начать искать решение, потому что, по-видимому, невозможно просто понять, почему логин завершается с ошибкой.

+0

спасибо, Майкл. С некоторой дополнительной отладкой я мог бы войти в систему. Теперь мне интересно, нужно ли мне запускать весь процесс входа в систему для каждого отдельного теста darn или если я могу сохранить сеанс, как только я проверил, что он работает? – Tom

ответ

2

Вы можете попробовать добавить echo $this->client->getResponse()->getContent(), чтобы показать вам реальный ответ, где вы могли бы искать ошибки

+0

Для ваших тестов, чтобы поддерживать изоляцию, вам нужно будет войти в систему для каждого из них. Вы можете добавить метод, аналогичный 'doLogin ($ username, $ password)' –

1

Создание AbstractControllerTest и создания авторизованного клиента на setUp() следующим образом:

abstract class AbstractControllerTest extends WebTestCase 
{ 
    /** 
    * @var Client 
    */ 
    protected $client = null; 


    public function setUp() 
    { 
     $this->client = $this->createAuthorizedClient(); 
    } 

    /** 
    * @return Client 
    */ 
    protected function createAuthorizedClient() 
    { 
     $client = static::createClient(); 
     $container = $client->getContainer(); 

     $session = $container->get('session'); 
     /** @var $userManager \FOS\UserBundle\Doctrine\UserManager */ 
     $userManager = $container->get('fos_user.user_manager'); 
     /** @var $loginManager \FOS\UserBundle\Security\LoginManager */ 
     $loginManager = $container->get('fos_user.security.login_manager'); 
     $firewallName = $container->getParameter('fos_user.firewall_name'); 

     $user = $userManager->findUserBy(array('username' => 'REPLACE_WITH_YOUR_TEST_USERNAME')); 
     $loginManager->loginUser($firewallName, $user); 

     // save the login token into the session and put it in a cookie 
     $container->get('session')->set('_security_' . $firewallName, 
      serialize($container->get('security.context')->getToken())); 
     $container->get('session')->save(); 
     $client->getCookieJar()->set(new Cookie($session->getName(), $session->getId())); 

     return $client; 
    } 
} 

Примечание: Пожалуйста , замените имя пользователя на свое тестовое имя пользователя.

Затем, расширяет AbstractControllerTest и использовать глобальную $client делать запросы следующим образом:

class ControllerTest extends AbstractControllerTest 
{ 
    public function testIndexAction() 
    { 
     $crawler = $this->client->request('GET', '/admin/'); 

     $this->assertEquals(
      Response::HTTP_OK, 
      $this->client->getResponse()->getStatusCode() 
     ); 
    } 
} 

Этот метод проверен и работает тонкие