想象一下,我们有一个简单的控制器,其中包含用于注册服务的方法。它只应在不退出时插入DB / File系统。 (我知道在SQL中这是可能的)
<?php
class ServiceController {
protected $c;
public function __construct($c){
$this->c = $c;
}
public function register($name, $protocol, $type){
$serviceMapper = $this->c['SerivceMapper'];
$service = new Service(); // entity
$service->setName($name);
$service->setProtocol($protocol);
$service->setType($type);
if (!$serviceMapper->exists($service)){
$serviceMapper->insert($service);
}
}
现在我要测试这个控制器。特别是如果在servicemapper上调用insert
方法。
有2个测试用例:服务已经退出时以及何时不存在。
我找到了一种测试方法,但看起来这是一种不好的做法,并且有一种更好的方法。
class ServiceControllerTest extends PHPUnit_Framework_TestCase {
public function testRegisterWhenItExists(){
$c = new Container();
$c['ServiceMapper'] = $this->getMockBuilder('ServicedMapper')
->disableOriginalConstructor()
->getMock();
$c['ServiceMapper']->expects($this->any())
->method('exists')
->will($this->returnValue(false));
$c['BackendMapper']->expects($this->any())
->method('insert')
->will($this->returnCallback(function($entity){
ServiceControllTest::insertExec = true;
}));
$serviceController = new ServiceController($c);
$serviceController->register('foo', 'bar', 'foobar');
$this->assertEquals(true, self::insertExec);
}
public function testRegisterWhenItDoesntExists(){
// Almost the same as in the other test
}
}
这是测试此方法的正确方法吗?有没有更好的方法?谢谢:))
编辑:我想我找到了正确的方法: public function testRegisterWhenItExists(){
$c = new Container();
$c['ServiceMapper'] = $this->getMockBuilder('ServicedMapper')
->disableOriginalConstructor()
->getMock();
$service = new Service();
$service->setName('foo');
$service->setProtocol('bar');
$service->setType('foobar');
$c['ServiceMapper']->expects($this->any())
->method('exists')
->with($this->equalTo($service))
->will($this->returnValue(false));
$c['BackendMapper']->expects($this->any())
->method('insert')
->with($this->equalTo($service));
$serviceController = new ServiceController($c);
$serviceController->register('foo', 'bar', 'foobar');
}
这是测试它的正确方法吗?
答案 0 :(得分:0)
我几乎可以肯定我找到了确保在模拟上调用函数的正确方法。
// This will assert that the "exists" function can be called 0,1 or more times
$c['ServiceMapper']->expects($this->any())
->method('exists')
->with($this->equalTo($service))
->will($this->returnValue(false));
// This will assert that the "exists" function can be called 0 times
// when the "exists" method is called, the unit test will fail
$c['ServiceMapper']->expects($this->never())
->method('exists')
->with($this->equalTo($service))
->will($this->returnValue(false));
完整文档位于http://phpunit.de/manual/3.7/en/test-doubles.html#test-doubles.mock-objects.tables.matchers