我的情景类似于以下内容:
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);
}
}
}
现在,我想测试ToMock::iReturn()
是否会返回150,ToTest::feedMe()
调用ToMock::callMe1()
一次使用5和10,ToMock::callMe2()
一次使用15和20。
我知道我可以模拟ToMock::iReturn
返回150,我也可以通过提供的参数来模拟ToMock
以期望一个特定的方法。但是,是否有可能在同一时间完成所有这些工作?如果是的话,它会是什么样子?
答案 0 :(得分:1)
如果我理解你的问题,那么测试代码可能看起来像
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);
}
}
答案 1 :(得分:1)
是的,是的。
以下是涵盖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
];
}
}
}
请注意使用expects()
和其他约束如何设置多个期望值。所有这些都可以很容易地结合起来。
供参考,见: