所以我正在为php api消费者库编写测试。在我的主要函数库之一:
public function __call($name, $args) {
return new Schema($name, $this);
}
在我的测试中,我使用嘲弄并做了类似的事情:
$schemaMock = m::mock('overload:Mynamespace\Schema');
这正好用模拟重载我的Schema类。所以后来当我这样做时:
$myclass->movies()
它应该调用__call
方法,从而调用模拟的Schema
类。到目前为止,这一切似乎都很好,但我想声明$ schemaMock是使用函数的名称构造的,在本例中是movies
以及传入的类的实例。我和# 39;我试过的是:
$schemaMock->shouldReceive('__construct')->with('movies');
然而,无论""是什么,我的测试都会通过。函数参数状态。 IE我可以将movies
更改为foobar
,测试仍然通过。我确定我遗漏了一些关于如何运行这些断言的简单方法。谢谢你的帮助!
答案 0 :(得分:0)
简短且最终答案:你不能。
通过将新类的代码拼凑在一起来定义模拟。它包含所有模拟方法的方法,对于所有其他方法,它是一个子类,它将原始类实现为其父类。 mock类不包含构造函数 - 对于普通的模拟对象,父类被调用。这是传递给Mockery::mock($class, $args)
的构造函数参数的方式。
但是例如模拟,需要复制模拟的构造函数。它隐藏在源代码内部,但是如果你看一下mockery/library/Mockery/Generator/StringManipulation/Pass/InstanceMockPass.php
,你会发现该方法的唯一目的是将属性和期望复制到新实例。参数被忽略了。
您可以获得的最佳近似是将实例化调用包装在一个可模拟的方法中,除了使用方法中的参数创建实例之外什么都不做 - 比如here:
public function instantiate ( $name, $args=array() ) {
if ( empty($args) )
return new $name();
else {
$ref = new ReflectionClass( $name );
return $ref->newInstanceArgs( $args );
}
}
或将构造函数中的实例化任务委托给可模拟的方法:
class Schema {
public function __construct () {
call_user_func_array( array( $this, 'init' ), func_get_args() );
}
public function init ($name, $obj) {
//...
}
}