phpunit避免模拟的构造函数参数
什么是避免phpunit不得不调用模拟对象的构造函数? 否则,我会需要一个模拟对象作为构造参数,另一个这样的api似乎是这样的:
getMock($className, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE)
我没有得到它的工作。 它仍然抱怨构造函数的参数,即使$callOriginalConstructor
设置为false。
我只有一个对象在构造函数中,它是一个dependency injection。 所以我不认为我有一个devise问题。
您可以使用getMockBuilder
而不是getMock
:
$mock = $this->getMockBuilder('class_name') ->disableOriginalConstructor() ->getMock();
有关详细信息,请参阅PHPUnit文档中的 “testing双精度”部分。
虽然你可以做到这一点,但不需要做得更好。 你可以重构你的代码,而不是需要注入的具体类(带有构造函数),而只依赖于一个接口。 这意味着你可以模拟或存根接口,而不必告诉PHPUnit修改构造函数的行为。
干得好:
// Get a Mock Soap Client object to work with. $classToMock = 'SoapClient'; $methodsToMock = array('__getFunctions'); $mockConstructorParams = array('fake wsdl url', array()); $mockClassName = 'MyMockSoapClient'; $callMockConstructor = false; $mockSoapClient = $this->getMock($classToMock, $methodsToMock, $mockConstructorParams, $mockClassName, $callMockConstructor);
作为一个附录,我想附加expects()
调用我的模拟对象,然后调用构造函数。 在PHPUnit 3.7.14中,调用disableOriginalConstructor()
时返回的对象实际上是一个对象。
// Use a trick to create a new object of a class // without invoking its constructor. $object = unserialize( sprintf('O:%d:"%s":0:{}', strlen($className), $className)
不幸的是,在PHP 5.4中有一个新的选项,他们没有使用:
ReflectionClass :: newInstanceWithoutConstructor
由于这是不可用的,我不得不手动反映类,然后调用构造函数。
$mock = $this->getMockBuilder('class_name') ->disableOriginalConstructor() ->getMock(); $mock->expect($this->once()) ->method('functionCallFromConstructor') ->with($this->equalTo('someValue')); $reflectedClass = new ReflectionClass('class_name'); $constructor = $reflectedClass->getConstructor(); $constructor->invoke($mock);
请注意,如果functionCallFromConstruct
protected
,则必须使用setMethods()
方法来模拟受保护的方法。 例:
$mock->setMethods(array('functionCallFromConstructor'));
setMethods()
必须在expect()
调用之前调用。 就我个人而言,在disableOriginalConstructor()
但在getMock()
之前,将其getMock()
。
也许你需要创build一个存根传入作为构造函数的参数。 那么你可以打破这一连串的模拟对象。
另外,你可以添加一个参数给getMock来防止调用默认的构造函数。
$mock = $this->getMock(class_name, methods = array(), args = array(), mockClassName = '', callOriginalConstructor = FALSE);
不过,我认为dave1010的答案看起来更好,这只是为了完整性。
PHPUnit被devise为在模拟对象上调用构造函数; 为了防止这种情况,你应该:
- 将一个模拟对象作为一个依赖项注入到您嘲笑的对象中
- 创build一个testing类来扩展您正在尝试调用的类,该类不调用父构造函数