我正在使用PHPUnit进行单元测试我使用模拟对象来测试是否使用正确的参数调用方法。当我只想这样做一次时,这很好用。
$logMock = $this->getMockBuilder('Logger')
->disableOriginalConstructor()
->getMock();
//check if it updates the correct record
$logMock->expects($this->exactly(1))
->method('updateLog')
->with(456, 'some status');
现在我想要测试是否第二次调用updateLog(使用不同的参数)。我不知道如何用'with'方法做到这一点。
有人有建议吗?
答案 0 :(得分:15)
我不知道你的嘲弄框架。通常你只是创造另一个期望。我认为这也应该适用于这个框架。
$logMock->expects($this->exactly(1))
->method('updateLog')
->with(100, 'something else');
修改强>
似乎PHPUnit框架不支持对同一方法的多个不同期望。根据此site,您必须使用索引功能。
它看起来像这样
$logMock->expects($this->at(0))
->method('updateLog')
->with(456, 'some status');
$logMock->expects($this->at(1))
->method('updateLog')
->with(100, 'something else');
$logMock->expects($this->exactly(2))
->method('updateLog');
答案 1 :(得分:1)
之前的回答是正确的。
您可以在PHPUnit手册中找到答案 http://www.phpunit.de/manual/3.6/en/phpunit-book.html#test-doubles.mock-objects.tables.matchers 搜索匹配器。 Matchers是函数any(),never()等返回的类... 你需要的是PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex,由方法返回()
您可以通过浏览PHPUnit类找到更多信息(添加到项目路径并使用类似netbeans的IDE跳转到它们并查看可以使用的内容)
答案 2 :(得分:1)
从PHPUnit 4.2开始,您可以使用withConsecutive
断言。前提是您知道呼叫的顺序。你的模拟看起来像这样:
$logMock->expects($this->exactly(2))
->method('updateLog')
->withConsecutive(
array(456, 'some status')
array(100, 'something else')
);
答案 3 :(得分:0)
<强> returnCallback 强>
如果您不能使用withConsecutive()
,可能是因为您使用的是旧版本的PHPUnit,那么您可以选择returnCallback
。
每次调用mock方法时都会调用returnCallback
函数。这意味着您可以保存传递给它的参数以供以后检查。例如:
$actualArgs = array();
$mockDependency->expects($this->any())
->method('setOption')
->will($this->returnCallback(
function($option, $value) use (&$actualArgs){
$actualArgs[] = array($option, $value);
}
));
$serviceUnderTest->executeMethodUnderTest();
$this->assertEquals(
array(
array('first arg of first call', 'second arg of first call'),
array('first arg of second call', 'second arg of second call'),
),
$actualArgs);