phpunit 模拟方法具有不同参数的多个调用
有没有办法为不同的输入参数定义不同的模拟期望?例如,我有一个名为DB的数据库层类。此类具有名为“Query( string $query )”的方法,该方法在输入时采用 SQL 查询字符串。是否可以为此类 (DB) 创建 mock,并为依赖于输入查询字符串的不同 Query 方法调用设置不同的返回值?
有没有办法为不同的输入参数定义不同的模拟期望?例如,我有一个名为DB的数据库层类。此类具有名为“Query( string $query )”的方法,该方法在输入时采用 SQL 查询字符串。是否可以为此类 (DB) 创建 mock,并为依赖于输入查询字符串的不同 Query 方法调用设置不同的返回值?
如果您可以避免使用它,那么使用它并不理想,因为正如他们的文档所声称的那样at()
at() 匹配器的 $index 参数是指给定模拟对象的所有方法调用中从零开始的索引。使用此匹配器时要小心,因为它可能导致与特定实现细节密切相关的脆性测试。
从4.1开始,您可以使用例如。withConsecutive
$mock->expects($this->exactly(2))
->method('set')
->withConsecutive(
[$this->equalTo('foo'), $this->greaterThan(0)],
[$this->equalTo('bar'), $this->greaterThan(0)]
);
如果要使其在连续调用时返回:
$mock->method('set')
->withConsecutive([$argA1, $argA2], [$argB1], [$argC1, $argC2])
->willReturnOnConsecutiveCalls($retValueA, $retValueB, $retValueC);
PHPUnit 模拟库(默认情况下)确定期望是否仅基于传递给参数的匹配器和传递给 的约束进行匹配。因此,两个仅在传递到的参数上不同的调用将失败,因为两个调用都将匹配,但只有一个将验证是否具有预期的行为。请参阅实际工作示例之后的复制案例。expects
method
expect
with
对于您的问题,您需要使用或->will($this->returnCallback(
如有关该主题的另一个问题
所述。->at()
<?php
class DB {
public function Query($sSql) {
return "";
}
}
class fooTest extends PHPUnit_Framework_TestCase {
public function testMock() {
$mock = $this->getMock('DB', array('Query'));
$mock
->expects($this->exactly(2))
->method('Query')
->with($this->logicalOr(
$this->equalTo('select * from roles'),
$this->equalTo('select * from users')
))
->will($this->returnCallback(array($this, 'myCallback')));
var_dump($mock->Query("select * from users"));
var_dump($mock->Query("select * from roles"));
}
public function myCallback($foo) {
return "Called back: $foo";
}
}
phpunit foo.php
PHPUnit 3.5.13 by Sebastian Bergmann.
string(32) "Called back: select * from users"
string(32) "Called back: select * from roles"
.
Time: 0 seconds, Memory: 4.25Mb
OK (1 test, 1 assertion)
<?php
class DB {
public function Query($sSql) {
return "";
}
}
class fooTest extends PHPUnit_Framework_TestCase {
public function testMock() {
$mock = $this->getMock('DB', array('Query'));
$mock
->expects($this->once())
->method('Query')
->with($this->equalTo('select * from users'))
->will($this->returnValue(array('fred', 'wilma', 'barney')));
$mock
->expects($this->once())
->method('Query')
->with($this->equalTo('select * from roles'))
->will($this->returnValue(array('admin', 'user')));
var_dump($mock->Query("select * from users"));
var_dump($mock->Query("select * from roles"));
}
}
phpunit foo.php
PHPUnit 3.5.13 by Sebastian Bergmann.
F
Time: 0 seconds, Memory: 4.25Mb
There was 1 failure:
1) fooTest::testMock
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-select * from roles
+select * from users
/home/.../foo.php:27
FAILURES!
Tests: 1, Assertions: 0, Failures: 1