Доктрина / хранилище издевательств с более чем одним методом
Я использую издевательство, чтобы проверить метод, который делает много обращений к хранилищу доктрин с разными хранилищами. Это метод, который я настроил все мои макеты репозитория:
public function testService()
{
$mockDoctrine = $this->getMockDoctrine();
$mockDoctrine->shouldReceive('getRepository')->once()
->andReturn($this->getRepositoryAMock());
$mockDoctrine->shouldReceive('getRepository')->once()
->andReturn($this->getRepositoryBMock());
$mockDoctrine->shouldReceive('getRepository')->once()
->andReturn($this->getRepositoryCMock());
//here is where i hit my test
$products = $this->service->fire(1, 1);
$this->assertInstanceOf('Illuminate\Support\Collection', $products);
foreach ($products as $v) {
$this->assertInstanceOf('Illuminate\Support\Collection', $v);
}
}
Это метод, который я издеваюсь по Доктрине:
public function getMockDoctrine()
{
$mockDoctrine = \App::make('Doctrine');
$mockDoctrine->shouldReceive('persist')
->andReturn(true);
$mockDoctrine->shouldReceive('flush')
->andReturn(true);
return $mockDoctrine;
}
Это мои репозитории макет
public function getRepositoryAMock()
{
$repository = \Mockery::mock('MyARepository');
$repository->shouldReceive('findBy')
->with(['paramA' => 1, 'paramB' => 1])
->andReturn($this->getMockA());
return $repository;
}
public function getRepositoryBMock()
{
$repository = \Mockery::mock('MyBRepository');
$repository->shouldReceive('findById')
->with(1)
->andReturn($this->getMockA());
return $repository;
}
public function getRepositoryCMock()
{
$repository = \Mockery::mock('MyCRepository');
$repository->shouldReceive('findOneBy')
->with(['paramA' => 1, 'paramB' => 1])
->andReturn($this->getMockA());
return $repository;
}
Это где на самом деле я установил возвращение моего макета
public function getMockA()
{
$obj = new MyClass();
$reflection = new \ReflectionClass($obj);
$id = $reflection->getProperty('id');
$id->setAccessible(true);
$id->setValue($obj, 1);
$obj
->setLogin('foo')
->setPassword('bar')
->setCode(1);
return $obj;
}
И тогда я получаю ошибку, как это:
1) MyClassTest:: testService BadMethodCallException: метод Mockery_2_ClassBRepository::findOneBy() не существует в этом фиктивном объекте
Предполагая, что у меня есть 3 метода с репозиториями, вызываемыми в методе testService(), метод, который не находит насмешка, находится в третьем, но издевательство думает, что он находится во втором, поэтому, очевидно, он не найдет, потому что во втором во-первых, не существует метода доктрины "findOneBy()" только в третьем.
Как я могу решить это?
2 ответа
Вы должны быть в состоянии использовать насмешки с ().
Например:
$mockDoctrine
->shouldReceive('getRepository')
->with('MyAReposiotry')->once()
->andReturn($this->getRepositoryAMock());
И так для каждого хранилища (с разными значениями в с).
Но я бы предпочел внедрить репозитории в этот сервис, а не получать его от менеджера сущностей внутри сервиса. Это намного лучше для тестирования. Посмотрите на это сообщение в блоге.
Благодаря мистеру Ивану,
Теперь мой метод работает.
В моем реальном классе я получал хранилище с классом сущностей,
лайк:
Doctrine::getRepository('MyEntityClassA')
->findBy(['paramA' => 1, 'paramB' => 1]);
поэтому я изменил свой тестовый метод, чтобы использовать "with", передавая класс сущности:
public function testService()
{
$mockDoctrine = $this->getMockDoctrine();
$mockDoctrine->shouldReceive('getRepository')
->with('MyEntityClassA')->once()
->andReturn($this->getRepositoryAMock());
$mockDoctrine->shouldReceive('getRepository')->once()
->with('MyEntityClassB')->once()
->andReturn($this->getRepositoryBMock());
$mockDoctrine->shouldReceive('getRepository')->once()
->with('MyEntityClassC')->once()
->andReturn($this->getRepositoryCMock());
//here is where i hit my test
$products = $this->service->fire(1, 1);
$this->assertInstanceOf('Illuminate\Support\Collection', $products);
foreach ($products as $v) {
$this->assertInstanceOf('Illuminate\Support\Collection', $v);
}
}