phpspec, Doctrine: проверка того, что для экземпляра объекта был задан параметр

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

у меня есть RepositoryFactory который имеет createRepository(EntityManager $em, $entityName)

доктрина-х EntityManager::getRepository($entityName) просто звонки RepositoryFactory::getRepository(EntityManager $em, $entityName) и если хранилище не существует, это вызывает RepositoryFactory::createRepository(EntityManager $em, $entityName)

Итак, в моем тесте, хранилище высмеивается из RepositoryFactory::getRepository,

class MyEntityManagerSpec extends ObjectBehavior
{
function let(..., MyRepositoryFactory $rfact, MyEntityRepository $repo, ...)
{
....

$rfact->getRepository(Argument::any(), Argument::any())
->willReturn($repo);

...
}

function it_sets_a_field_on_repositories(MyEntityRepository $repo)
{
//This class calls its own getRepository, which calls
//getRepository on the factory, which ->willReturn($repo).
//So, effectively (but without mocking the SUT) that means
//$this->getRepository($entityName)->willReturn($repo)

$entityName = 'blah\blah\FakeEntity';

$repo->setField(Argument::any())->shouldBeCalled();
//The above fails with
//"No calls that match MyEntityRepository\P112->setField(*)"
$gotRepo = $this->getRepository($entityName);

$repo->setField(Argument::any())->shouldHaveBeenCalled();
//This fails in the same way

$gotRepo->shouldBe($repo);
//This test passes but doesn't let me verify the property was set
//and is therefore of little help to me

$gotRepo->getField()->shouldNotBeNull();
//I wanted to use shouldBe/shouldHaveBeenCalled but if the field's
//been set that's just as good. Except this fails as well, with
//"is_null(null) not expected to return true, but it did."}

Теперь, прежде чем начнутся ответы о тестировании в изоляции, я это понимаю. Я впервые начал пытаться написать проверку для установки поля в MyRepositoryFactory::createRepository но такая же проблема возникла — если я делаю объект внутри createRepository, то у меня нет издевательств для проверки с shouldBe / shouldHaveBeenCalled. Но я пытаюсь все сделать правильно, поэтому, если это неподходящее место для моего теста, я бы предпочел много рефакторинга, чем проходить хакерский тест.

РЕДАКТИРОВАТЬ: это фактический бит тестируется

class MyEntityManager
{
...

public function getRepository($entityName)
{
$repo = parent::getRepository($entityName);

$metaData = $this->getClassMetadata($entityName);

$flag = $this->getTarget() && $metaData->reflClass
->implementsInterface('Caj\Bundle\NameOfBundle\Model\NameOfBundleInterface');

if($flag) {
$repo->setField($this->getField());
}
return $repo;
}
}

$ Repo в приведенном выше бите — это то, что должно быть здесь посмеяно; parent::getRepository ==> RepositoryFactory::getRepository ==> RepositoryFactory::createRepository

Кроме того, я знаю, что тест попадает в if($flag) блок, но код внутри не работает. $this->getField() работает и возвращается нормально, но $repo->setField все еще получает ноль. $repo->setField($field) нормальный сеттер без лишней логики.

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]