Seb*_*uer 6 php phpunit factory-pattern
我使用Factories(请参阅http://www.php.net/manual/en/language.oop5.patterns.php获取模式)来增加代码的可测试性.一个简单的工厂看起来像这样:
class Factory
{
public function getInstanceFor($type)
{
switch ($type) {
case 'foo':
return new Foo();
case 'bar':
return new Bar();
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下是使用该工厂的示例类:
class Sample
{
protected $_factory;
public function __construct(Factory $factory)
{
$this->_factory = $factory;
}
public function doSomething()
{
$foo = $this->_factory->getInstanceFor('foo');
$bar = $this->_factory->getInstanceFor('bar');
/* more stuff done here */
/* ... */
}
}
Run Code Online (Sandbox Code Playgroud)
现在进行适当的单元测试,我需要模拟将返回类的存根的对象,这就是我遇到的问题.我认为有可能这样做:
class SampleTest extends PHPUnit_Framework_TestCase
{
public function testAClassUsingObjectFactory()
{
$fooStub = $this->getMock('Foo');
$barStub = $this->getMock('Bar');
$factoryMock = $this->getMock('Factory');
$factoryMock->expects($this->any())
->method('getInstanceFor')
->with('foo')
->will($this->returnValue($fooStub));
$factoryMock->expects($this->any())
->method('getInstanceFor')
->with('bar')
->will($this->returnValue($barStub));
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我运行测试时,这就是我得到的:
F
Time: 0 seconds, Memory: 5.25Mb
There was 1 failure:
1) SampleTest::testDoSomething
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-bar
+foo
FAILURES!
Tests: 1, Assertions: 0, Failures: 1.
Run Code Online (Sandbox Code Playgroud)
所以显然不可能让mock对象根据传递的方法参数返回不同的值.
如何才能做到这一点?
问题是PHPUnit Mocking不允许你这样做:
$factoryMock->expects($this->any())
->method('getInstanceFor')
->with('foo')
->will($this->returnValue($fooStub));
$factoryMock->expects($this->any())
->method('getInstanceFor')
->with('bar')
->will($this->returnValue($barStub));
Run Code Online (Sandbox Code Playgroud)
你只能有一个expects
每个->method();
.它不知道参数->with()
不同的事实!
所以你只需->expects()
用第二个覆盖第一个.这些断言是如何实现的,并不是人们所期望的.但有一些解决方法.
您需要使用行为/返回值定义一个期望值!
看到: Mock in PHPUnit - multiple configuration of the same method with different arguments
在将示例调整为您的问题时,它可能如下所示:
$fooStub = $this->getMock('Foo');
$barStub = $this->getMock('Bar');
$factoryMock->expects($this->exactly(2))
->method('getInstanceFor')
->with($this->logicalOr(
$this->equalTo('foo'),
$this->equalTo('bar')
))
->will($this->returnCallback(
function($param) use ($fooStub, $barStub) {
if($param == 'foo') return $fooStub;
return $barStub;
}
));
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4532 次 |
最近记录: |