12

有没有办法用 phpunit 创建一个模拟类,而不是一个模拟对象?我正在寻找一种方法来进行依赖注入,而不必显式传递类可能需要在构造函数(或任何地方)中使用的每个对象。对于所有这些情况都会返回“true”的东西:

public function testAAAA()
{
  $foo = $this->getMock('foo', array('bar'));
  var_dump(class_exists('foo', false));
  var_dump(method_exists('foo', 'bar'));
  var_dump(method_exists($foo, 'bar'));
}

这打印:

bool(true)
bool(false)
bool(true)

表明虽然它确实成功地创建了一个假的 'foo' 类,但它没有绑定一个 'bar' 方法到它。

我正在使用 phpunit 3.7.5。

4

1 回答 1

14

我怀疑您实际上并不想这样做(因为您可以使用 PHPUnit 的 mockbuilder 禁用构造函数等,请参阅文档),但假设您确实想要或需要这样做,这应该可以解决问题:

$foo = $this->getMockBuilder('nonexistant')
        ->setMockClassName('foo')
        ->setMethods(array('bar'))
        ->getMock();

    var_dump(class_exists('foo', false));
    var_dump(method_exists('foo', 'bar'));
    var_dump(method_exists($foo, 'bar'));

    $cls = new ReflectionClass('foo');
    var_dump($cls->hasMethod('bar'));

老实说,我不确定为什么需要在上面指定不同的名称(不存在和 foo)的细节,但它似乎与 PHPUnit 的行为有关,当被模拟的类还不存在时,并且 setMockClassName 生成一个类扩展该类。或者其他的东西。它可能有效地解决了错误/边缘情况——这是库的奇怪用法。你应该可以getMock单独通过函数做同样的事情,只是更丑。

顺便说一句,听起来您应该熟悉php 的反射功能。它不是最强大的反射库,但它非常好。我已经使用它根据类的构造函数参数和“模型”库的属性生成有关必需字段和可选字段的元信息,其中该元信息用于生成接受正确类型值的表单。也就是说,生成类型化的表单,无需表单所针对的类的实例,也无需手写大量愚蠢的代码——整个功能总共大约 100 行。显然我不知道你想做什么,但从你帖子中的少量信息来看,我猜它更接近那种类型的元事物。

于 2012-11-15T00:55:05.617 回答