0

EDIT

actually answered this myself, was so simple:

$session = $this->getMock(
  '\Symfony\Component\HttpFoundation\Session\Session',
  array(),
  array(),
  '',
  false // don't call constructor
);
$container->register('session', $session);

mocking the session object within the phpunit bootstrap file.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

it seems to me to be impossible to test this properly.

i am using Symfony 2 standalone components - not using FrameworkBundle etc etc. I have a controller, which in turn creates a form, which then (attempts to) add the Csrf Extension to the form builder.

However, passing in a session object simply gives me:

RuntimeException: Failed to start the session because headers have already been sent.

some code that produces this:

$session = $this->container->get('session') // instance of Symfony\Component\HttpFoundation\Session\Session
$form_obj = new MyForm(); // extends AbstractType
$secret   = $form_obj->getName(); // something random
$form_obj->addExtension(new CsrfExtension(new SessionCsrfProvider($session, $secret)));

OK, so the session can't start because PHPUnit sends output first. putting session_start();

at the top of the bootstrap file DOES NOT help, or work.

RuntimeException: Failed to start the session because a session has already been started

and in any case, that's a fudge fix as you wouldn't start a session in 2 different places anyway.

so next, i tried to register a mock session object as per these instructions: http://symfony.com/doc/master/components/http_foundation/session_testing.html

but, sadly the SessionCsrfProvider interface requires:

Argument 1 passed to 
Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider::__construct() 
must be an instance of Symfony\Component\HttpFoundation\Session\Session, 
instance of 
Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage given

so ... i cannot actually use the SessionCsrfProvider within any test code, unless i provide the session into it as a PHPUnit mock ... but then that would require me to alter the design of the code to inject a session object into a constructor or parameter as some method that calls that addExtension() method. Currently, the above piece of code that adds the extension, is wrapped within a function itself, so this would mean making it required to pass in a session object manually, which i really dont want to introduce.

any ideas?

4

1 回答 1

0

我知道我对此有点晚了,但另一种更好的方法是使用 Symfonys MockArraySessionStorage。

$session = new Session(new MockArraySessionStorage());

$csrfProvider = new SessionCsrfProvider($session, $secret);
于 2013-06-20T20:24:15.473 回答