给定这个类:
class MyBuilder {
public function build($param1, $param2) {
// build dependencies ...
return new MyClass($dep1, $dep2, $dep3);
}
}
如何对这个类进行单元测试?
单元测试意味着我想测试它的行为,所以我想测试它是否用正确的依赖关系构建了我的对象。但是,new
指令是硬编码的,我无法模拟它。
现在,我已经添加了类名作为参数(这样我就可以提供模拟类的类名),但它很难看:
class MyBuilder {
public function build($classname, $param1, $param2) {
// build dependencies ...
return new $classname($dep1, $dep2, $dep3);
}
}
是否有干净的解决方案或设计模式使我的工厂可测试?
最佳答案
工厂本质上是可测试的,您只是试图对实现进行过于严格的控制。
您将检查您是否通过 $this->assertInstanceOf()
获得了您的类的实例。然后使用生成的对象,您将确保正确设置属性。为此,您可以使用任何公共(public)访问器方法或使用 PHPUnit 中可用的 $this->assertAttribute*
方法。
许多常见断言还能够检查 protected 属性和私有(private)属性的属性。
我不会在你的参数列表中指定类名,因为你的用法是工厂将只返回一种类型,而且只有依赖项被改变了。让它返回模拟对象类型是不必要的,并且会使您的测试更加复杂。
测试最终看起来像这样:
public function testBuild() {
$factory = new MyBuilder();
//I would likely put the following into a data provider
$param1 = 'foo';
$param2 = 'bar';
$depen1 = 'boo';
$depen2 = 'baz';
$depen3 = 'boz';
$object = $factory->build($param1, $param2);
$this->assertInstanceOf('MyClass', $object);
//Check the object definition
//This would change depending on your actual implementation of your class
$this->assertAttributeEquals($depen1, 'attr1', $object);
$this->assertAttributeEquals($depen2, 'attr2', $object);
$this->assertAttributeEquals($depen3, 'attr3', $object);
}
您现在要确保您的工厂返回一个正确的对象。首先确保它是正确的类型。然后确保它已正确初始化。
您依赖于 MyClass
的存在来使测试通过,但这并不是一件坏事。您的工厂旨在创建 MyClass
对象,因此如果该类未定义,那么您的测试肯定会失败。
在开发过程中测试失败也不是坏事。
关于php - 如何测试工厂类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20302156/