[英]PHPUnit mock return value and number of times called with specific argument for different methods same class
My scenario is similar to below: 我的情况类似于以下内容:
class ToMock
{
public function iReturn()
{
return time();
}
public function callMe1($arg1, $arg2)
{
return true;
}
public function callMe2($arg1, $arg2)
{
return true;
}
}
class ToTest
{
public function feedMe(ToMock $toMock)
{
if ($toMock->iReturn() > 100) {
$toMock->callMe1(5, 10);
}
if ($toMock->iReturn() < 200) {
$toMock->callMe2(15, 20);
}
}
}
Now, I want to test if ToMock::iReturn()
returns 150, ToTest::feedMe()
calls ToMock::callMe1()
once with 5 and 10, and ToMock::callMe2()
once with 15 and 20. 现在,我想测试
ToMock::iReturn()
返回150, ToTest::feedMe()
ToMock::callMe1()
以5和10调用ToMock::callMe1()
,以及ToMock::callMe2()
以15和20 ToMock::callMe2()
。
I know I can mock the ToMock::iReturn
to return 150, also I can mock ToMock
to expect a particular method once with supplied argument. 我知道我可以模拟
ToMock::iReturn
返回150,也可以模拟ToMock
使用提供的参数来期待一次特定的方法。 But, is it possible to do all of these together in the same time? 但是,是否可以同时进行所有这些操作? if yes, how would it look like?
如果是,它看起来如何?
If I understood your question correctly then test code could look like 如果我正确理解了您的问题,则测试代码可能如下所示
class MockingExpectationsTest extends PHPUnit_Framework_TestCase
{
private $obj;
private $mock;
public function setUp(){
$this->mock = $this->createMock(ToMock::class);
$this->obj = new ToTest();
}
public function testExpectations(){
$this->mock->expects($this->exactly(2))
->method('iReturn')
->willReturn(150);
$this->mock->expects($this->exactly(1))
->method('callMe1')
->with(5, 10);
$this->mock->expects($this->exactly(1))
->method('callMe2')
->with(15, 20);
$this->obj->feedMe($this->mock);
}
}
Yes, it is. 是的。
Here's an example of a test that covers ToTest
: 这是涵盖
ToTest
的测试ToTest
:
<?php
use PHPUnit\Framework\TestCase;
class ToTestTest extends TestCase
{
/**
* @dataProvider providerTimeBetween0And100
*
* @param int $time
*/
public function testFeedMeWhenTimeIsBetween0And100($time)
{
$toMock = $this->createMock(ToMock::class);
$toMock
->expects($this->exactly(2))
->method('iReturn')
->willReturn($time);
$toMock
->expects($this->never())
->method('callMe1');
$toMock
->expects($this->once())
->method('callMe2')
->with(
$this->identicalTo(15),
$this->identicalTo(20)
);
$toTest = new ToTest();
$toTest->feedMe($toMock);
}
public function providerTimeBetween0And100()
{
return $this->providerTimeBetween(0, 100);
}
/**
* @dataProvider providerTimeBetween101And199
*
* @param int $time
*/
public function testFeedMeWhenTimeIsBetween101And199($time)
{
$toMock = $this->createMock(ToMock::class);
$toMock
->expects($this->exactly(2))
->method('iReturn')
->willReturn($time);
$toMock
->expects($this->once())
->method('callMe1')
->with(
$this->identicalTo(5),
$this->identicalTo(10)
);
$toMock
->expects($this->once())
->method('callMe2')
->with(
$this->identicalTo(15),
$this->identicalTo(20)
);
$toTest = new ToTest();
$toTest->feedMe($toMock);
}
public function providerTimeBetween101And199()
{
return $this->providerTimeBetween(101, 199);
}
/**
* @dataProvider providerTimeGreaterThan199
*
* @param int $time
*/
public function testFeedMeWhenTimeIsGreaterThan199($time)
{
$toMock = $this->createMock(ToMock::class);
$toMock
->expects($this->exactly(2))
->method('iReturn')
->willReturn($time);
$toMock
->expects($this->once())
->method('callMe1')
->with(
$this->identicalTo(5),
$this->identicalTo(10)
);
$toMock
->expects($this->never())
->method('callMe2');
$toTest = new ToTest();
$toTest->feedMe($toMock);
}
public function providerTimeGreaterThan199()
{
return $this->providerTimeBetween(200, 300);
}
private function providerTimeBetween($min, $max)
{
for ($time = $min; $time < $max; ++$time) {
yield [
$time
];
}
}
}
Note how multiple expectations are set up using expects()
and further constraints. 注意如何使用
expects()
和更多约束来设置多个期望。 All of these can be easily combined. 所有这些都可以轻松组合。
For reference, see: 供参考,请参阅:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.