phpunit:嘲笑类型提示的抽象类?

时间:2018-04-25 22:49:09

标签: mocking phpunit

我正在尝试测试一个辅助函数,它接受process的一些实例,一个带有单个抽象方法的抽象类function get_field_class(Form $form, $field) { return $form->get_errors_for($field) ? 'error' : ''; } (实际上并没有从测试函数调用)。

Form

我的问题是,如何模拟抽象的get_field_class类,以便它被$form = $this->getMockForAbstractClass(Form::class) ->method('process') ->will($this->returnValue(true)); $this->assertEquals('error', $this->wrapper->get_field_class($form, 'foo')); 的类型注释接受?

我试过直接传递模拟实例:

$form = $this->getMockBuilder(Form::class)
  ->setMockClassName(Form::class)
  ->getMockForAbstractClass(Form::class)
  // ...

这会引发TypeError:参数1 ...必须是Form的实例,PHPUnit \ Framework \ MockObject \ Builder \ InvocationMocker的实例

我已尝试明确设置模拟类名称:

$form = $this->getMockBuilder(Form::class)
  ->disableAutoload()
  ->setMockClassName(Form::class)
  ->getMockForAbstractClass(Form::class)
  // ...

这会抛出警告类“表单”已存在。 (警告会在我的配置中被提升为异常或错误,因此这不是一个可接受的解决方案。)

我试过禁用自动加载(也许phpunit是出于某种原因急切地加载Form类的?):

AppName

这只会引发警告:类“表单”不存在。

1 个答案:

答案 0 :(得分:0)

在您的第一个不起作用的示例中,您实际上并未传递模拟对象。为了实现这一点,代码需要是:

$form = $this->getMockForAbstractClass(Form::class);

$form->expects($this->once())
  ->method('process')
  ->will($this->returnValue(true));

$this->assertEquals('error', $this->wrapper->get_field_class($form, 'foo'));

will()返回一个PHPUnit用来验证模拟对象被正确调用的对象。

正如在评论中提到的,从MockBuilder调用中删除setMockClassName将起作用。

$form = $this->getMockBuilder(Form::class)
  ->getMockForAbstractClass(Form::class);

再次使用此表单,您需要单独设置对process的调用的期望。

您得到的错误是因为该类已经存在,并且PHP不允许您创建两个具有相同名称的类。您无需为此设置名称,因为PHPUnit将创建一个扩展您的Form类的新对象。

看一下PHPUnit文档中的示例: https://phpunit.readthedocs.io/en/7.1/test-doubles.html#mocking-traits-and-abstract-classes

<?php
use PHPUnit\Framework\TestCase;

abstract class AbstractClass
{
    public function concreteMethod()
    {
        return $this->abstractMethod();
    }

    public abstract function abstractMethod();
}

class AbstractClassTest extends TestCase
{
    public function testConcreteMethod()
    {
        $stub = $this->getMockForAbstractClass(AbstractClass::class);

        $stub->expects($this->any())
             ->method('abstractMethod')
             ->will($this->returnValue(true));

        $this->assertTrue($stub->concreteMethod());
    }
}
?>