我有一个Service类和一个测试类,请按照以下步骤操作:
课程
class MyCustomService
{
public function job()
{
while($this->getResponseFromThirdPartyApi()->data) {
// do some stuff...
}
return ...
}
protected function getResponseFromThirdPartyApi()
{
// Here do some curl and return stdClass
// data attribute is populated only on first curl request
}
}
测试模拟getResponseFromThirdPartyApi方法
class MyCustomServiceTest
{
public function testJobImportingData()
{
$myCustomServiceMock = $this->getMockBuilder('MyCustomService')
->setMethods(array('getResponseFromThirdPartyApi'))
->getMock();
$myCustomServiceMock->expects($this->any())
->method('getResponseFromThirdPartyApi')
->willReturn($this->getResponseWithData());
$jobResult = $myCustomServiceMock->job();
// here some assertions on $jobResult
}
protected function getResponseWithData()
{
$response = new \stdClass;
$response->data = ['foo', 'bar'];
return $response;
}
}
在第一次调用MyCustomService的while循环后,如何更改getResponseWithData返回?
我尝试在MyCustomServiceTest上创建自定义标志并检查getResponseWithData,但是一旦该模拟对象不再在MyCustomServiceTest上再次调用getResponseWithData方法,则会失败。
任何方向?
答案 0 :(得分:0)
正如Nico Haase上面建议的那样,路径是使用回调。
经过一些研究,我实现了将模拟对象引用传递给模拟方法并检查标志,结果如下:
class MyCustomServiceTest
{
public function testJobImportingData()
{
$myCustomServiceMock = $this->getMockBuilder('MyCustomService')
->setMethods(array('getResponseFromThirdPartyApi'))
->getMock();
$myCustomServiceMock->expects($this->any())
->method('getResponseFromThirdPartyApi')
->will($this->returnCallback(
function () use ($myCustomServiceMock) {
return $this->getResponseWithData($myCustomServiceMock)
}
));
$jobResult = $myCustomServiceMock->job();
// here some assertions on $jobResult
}
protected function getResponseWithData(&$myCustomServiceMock)
{
$response = new \stdClass;
if (isset($myCustomServiceMock->imported)) {
$response->data = false;
return $response;
}
$myCustomServiceMock->imported = true;
$response = new \stdClass;
$response->data = ['foo', 'bar'];
return $response;
}
}
然后while循环将仅被调用一次,我们将能够进行无永久循环的测试。