PHPUnit насмешливый объект не работает
Я новичок в насмешливых объектах в PHPUnit и не могу заставить его работать. Я строю расширение текущего SensioGeneratorBundle
(для Symfony2). Я использую PHPUnit 3.7, установленный через PEAR
, Он работает на PHP 5.3.5 (поскольку PEAR установлен в этой версии).
Мои раздетые классы:
ControllerGenerator.php
class ControllerGenerator extends Generator
{
// ...
public function generate(BundleInterface $bundle, $controller, array $actions = array())
{
// ...
}
}
GenerateControllerCommand.php
class GenerateControllerCommand extends ContainerAwareCommand
{
private $generator;
/**
* @see Command
*/
public function configure()
{
// ...
}
public function execute(InputInterface $input, OutputInterface $output)
{
// ...
$generator = $this->generator;
$generator->generate($bundle, $controller);
// ...
}
protected function getGenerator()
{
if (null === $this->generator) {
$this->generator = new ControllerGenerator($this->getContainer()->get('filesystem'), __DIR__.'/../Resources/skeleton/bundle');
}
return $this->generator;
}
public function setGenerator(ControllerGenerator $generator)
{
$this->generator = $generator;
}
}
GenerateControllerCommandTest.php
class GenerateControllerCommandTest extends GenerateCommandTest
{
public function testNonInteractiveCommand()
{
$bundle = 'FooBarBundle';
$controller = 'PostController';
$input = array(
'command' => 'generate:controller',
'--bundle' => $bundle,
'--controller' => $controller,
);
$application = $this->getApplication();
$commandTester = $this->getCommandTester($input);
$generator = $this->getGenerator();
$generator
->expects($this->once())
->method('generate')
->with($this->getContainer()->get('kernel')->getBundle($bundle), $controller)
;
$commandTester->execute($input, array('interactive' => false));
}
protected function getCommandTester($input = '')
{
return new CommandTester($this->getCommand($input));
}
protected function getCommand($input = '')
{
return $this->getApplication($input)->find('generate:controller');
}
protected function getApplication($input = '')
{
$application = new Application();
$command = new GenerateControllerCommand();
$command->setContainer($this->getContainer());
$command->setHelperSet($this->getHelperSet($input));
$command->setGenerator($this->getGenerator());
$application->add($command);
return $application;
}
protected function getGenerator()
{
// get a noop generator
return $this
->getMockBuilder('Sensio\Bundle\GeneratorBundle\Generator\ControllerGenerator')
->disableOriginalConstructor()
->setMethods(array('generate'))
->getMock()
;
}
}
Когда я запускаю PHPUnit, я получаю эту ошибку:
$ phpunit Tests\Command\GenerateControllerCommandTest
PHPUnit 3.7.0 by Sebastian Bergmann.
Configuration read from E:\Wouter\web\wamp\www\wjsnip\vendor\sensio\generator-bundle\Sensio\Bundle\GeneratorBundle\phpunit.xml.dist
F
Time: 2 seconds, Memory: 7.25Mb
There was 1 failure:
1) Sensio\Bundle\GeneratorBundle\Tests\Command\GenerateControllerCommandTest::testNonInteractiveCommand
Expectation failed for method name is equal to <string:generate> when invoked 1 time(s).
Method was expected to be called 1 times, actually called 0 times.
E:\Wouter\web\wamp\bin\php\php5.3.5\PEAR\phpunit:46
FAILURES!
Tests: 1, Assertions: 7, Failures: 1.
Почему я получаю эту ошибку? Я думаю, что я назвал generate
команда в GenerateControllerCommand::execute
метод? Я делаю что-то не так, возможно, правда? Или это ошибка в PHPunit?
1 ответ
Короче
Вы генерируете два разных $generator
объекты. Звонок происходит с одним, а другой expect
сидеть.
дольше
Вы меняете поведение protected function getGenerator()
но оригинальная функция ожидает, что вызов этой функции заполняет $this->generator
,
Ваш тест не работает, поскольку вы и функция ожидаете, что всегда получите один и тот же генератор, а с вашим перезаписанием функция возвращает два разных объекта.
Вы устанавливаете ожидаемый вызов на один, и вызов происходит с объектом.
Просто смотрю на:
$generator = $this->getGenerator();
$generator
->expects($this->once())
->method('generate')
->with($this->getContainer()->get('kernel')->getBundle($bundle), $controller)
;
$commandTester->execute($input, array('interactive' => false));
}
$generator
переменная нигде не помещается ни в одну область видимости объекта и, следовательно, никакие вызовы не могут произойти, так как каждый $this->getGenerator()
создает новый объект, который нигде не хранится.
Так в
protected function getApplication() {
//...
$command->setGenerator($this->getGenerator());
//...
}
у вас есть другой объект, чем у вас в тестовом примере.