用phpunit创建一个mock类?

时间:2012-11-14 23:54:19

标签: php phpunit

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

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。

1 个答案:

答案 0 :(得分:13)

我怀疑你实际上并不想这样做(因为你可以使用PHPUnit的mockbuilder禁用构造函数等,请参阅the docs),但假设你确实需要或需要,这应该做的伎俩:

$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生成一个扩展该类的类。或者其他的东西。它可能有效地解决了一个bug /边缘案例 - 这是库的奇怪用法。你应该能够仅通过getMock函数做同样的事情,这只是更加丑陋。

顺便说一句,听起来你应该熟悉php's reflection capabilities。它不是那里最强大的反射库,但它非常好。我已经用它来生成关于类的必需和可选字段的元信息,这些信息基于它们的构造函数参数和“模型”库的属性,其中元信息用于生成接受正确类型值的表单。也就是说,生成类型化的表单,没有表单所用类的实例,并且无需手工编写愚蠢的代码量 - 整个功能总共约为100行。显然我不知道你要做什么,但是根据帖子中的少量信息,我猜它更接近于那种类型的元素而不是。