我有一个类似于此的类(为简洁起见,删除了一些逻辑):
class FooCollection {
protected $_foos;
public function __construct() {
$this->_foos = new SplObjectStorage();
}
public function addFoo(FooInterface $foo) {
$this->_foos->attach($foo);
}
public function removeFoo(FooInterface $foo) {
$this->_foos->detach($foo);
}
}
Run Code Online (Sandbox Code Playgroud)
我想用PHPUnit 来测试addFoo()和removeFoo()方法,我想知道最好的策略是什么呢?据我所知,我只有几个选择:
hasFoo(FooInterface $foo)并在添加后检查此方法.getFoos()直接返回SplObjectStorage实例的方法,并$foo在添加后检查是否在其中.removeFoo($foo)之后addFoo($foo)并检查异常.$_foos公共财产并在添加后直接检查(坏,坏,坏......).选项#1和#2正在改变公共接口仅用于测试目的,我不确定我对此的看法.它们似乎是非常通用的,有用的方法,但在我的特定情况下,我从来不需要检查Foo集合中特定实例的存在,也不需要检索所有实例,所以它真的会只是臃肿.此外,似乎如果我在一次测试中测试界面的多个部分,我不是真的在测试一个"单位",但这或多或少只是一个哲学挂断.
选项#3对我来说似乎很尴尬.
选项#4是一个非常糟糕的主意,我甚至不应该列出它,因为即使在这里建议,我也不会这样做.
为什么不创建一个SplObjectStorage传递给构造函数的模拟对象?然后你可以断言在mock上调用attach和detach方法.
function testAttachFOO() {
$mockStorage = $this->getMockBuilder('SplObjectStorage')
->setMethods(array('attach'))
->getMock();
$mockFoo = $this->getMock('FooInterface');
$mockStorage->expects($this->once())
->method('attach')
->with($mockFoo);
$collection = new FooCollection($mockStorage);
$collection->addFoo($mockFoo);
}
Run Code Online (Sandbox Code Playgroud)
和类似的东西removeFoo.
这样做需要您更改构造函数,以便您可以注入依赖项.但IMO使得代码更加清晰.也使测试更容易.
所以构造函数变成:
public function __construct(SPLObjectStorage $storage) {
$this->_foos = $storage;
}
Run Code Online (Sandbox Code Playgroud)
如果这个类变得难以构建,那就表明该类做得太多,应该重构为更多更小的类.
| 归档时间: |
|
| 查看次数: |
1816 次 |
| 最近记录: |