具有不止一种方法的嘲弄学说/存储库
Mockery Doctrine / Repository with more than one method
我正在使用 mockery 来测试一种方法,该方法对不同的存储库进行大量学说存储库调用。
这是我设置所有存储库模拟的方法:
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);
}
}
这是我模拟Doctrine的方法:
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;
}
这是我设置模拟 return 的地方
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() 方法中调用存储库,mockery 没有找到的方法在第三个,但 mockery 认为它在第二个,所以显然他不会找到, 因为在第二个中, 不存在 "findOneBy()" 学说方法只是在第三个中.
我该如何解决这个问题?
你应该可以使用 mockery 的 with()。
例如:
$mockDoctrine
->shouldReceive('getRepository')
->with('MyAReposiotry')->once()
->andReturn($this->getRepositoryAMock());
每个存储库都是这样(with 中有不同的值)。
但我宁愿在该服务中注入存储库,而不是从服务内部的实体管理器获取它。它更适合测试。看看this blog post.
感谢 Ivan 先生,
现在我的方法奏效了。
在我的真实 class 中,我正在获取包含实体 class、
的存储库
喜欢:
Doctrine::getRepository('MyEntityClassA')
->findBy(['paramA' => 1, 'paramB' => 1]);
所以我更改了我的测试方法以使用 "with" 传递实体 class:
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);
}
}
我正在使用 mockery 来测试一种方法,该方法对不同的存储库进行大量学说存储库调用。 这是我设置所有存储库模拟的方法:
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);
}
}
这是我模拟Doctrine的方法:
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;
}
这是我设置模拟 return 的地方
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() 方法中调用存储库,mockery 没有找到的方法在第三个,但 mockery 认为它在第二个,所以显然他不会找到, 因为在第二个中, 不存在 "findOneBy()" 学说方法只是在第三个中.
我该如何解决这个问题?
你应该可以使用 mockery 的 with()。
例如:
$mockDoctrine
->shouldReceive('getRepository')
->with('MyAReposiotry')->once()
->andReturn($this->getRepositoryAMock());
每个存储库都是这样(with 中有不同的值)。
但我宁愿在该服务中注入存储库,而不是从服务内部的实体管理器获取它。它更适合测试。看看this blog post.
感谢 Ivan 先生,
现在我的方法奏效了。
在我的真实 class 中,我正在获取包含实体 class、
的存储库
喜欢:
Doctrine::getRepository('MyEntityClassA')
->findBy(['paramA' => 1, 'paramB' => 1]);
所以我更改了我的测试方法以使用 "with" 传递实体 class:
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);
}
}