如何使用PHPUnit中的数据提供程序测试异常?

aut*_*tix 6 php phpunit unit-testing

PHPUnit具有一个非常有用的功能@dataProvider,它可以测试一个方法的多种情况。它还具有另一个很酷的注释- @expectedException确保应用程序Exception在定义的位置正确投掷。

我目前正在针对多种边缘情况测试一种方法,并希望将以下两个功能结合起来(不工作代码):

class TestMyClass
{
    /**
     * @dataProvider provideDataForFoo
     */
    public function testFoo($paramBar, $paramBuz, $expected)
    {
        $myObject = new MyClass();
        $this->assertEquals($expected, $myObject->foo($paramBar, $paramBuz));
    }
    public function provideDataForFoo()
    {
        return [
            ['expected lorem', 'bar lorem', 'buz lorem'],
            ['expected ipsum', 'bar ipsum', 'buz ipsum'],
            ['expected exception', 'bar invalid argument', 'buz invalid argument'],
        ];
    }
}
Run Code Online (Sandbox Code Playgroud)

使用时是否可能/如何@expectedException使用@dataProvider

aut*_*tix 7

PHPUnit 不提供这种组合。但这可以通过一个简单的技巧来实现:

  1. 基本解决方案

用于正常和异常测试的单独测试方法。

class TestMyClass
{
    /**
     * @dataProvider provideDataForFoo
     */
    public function testFoo($paramBar, $paramBuz, $expected)
    {
        $myObject = new MyClass();
        $this->assertEquals($expected, $myObject->foo($paramBar, $paramBuz));
    }
    public function provideDataForFoo()
    {
        return [
            ['expected lorem', 'bar lorem', 'buz lorem'],
            ['expected ipsum', 'bar ipsum', 'buz ipsum'],
        ];
    }
    /**
     * @dataProvider provideDataForFooException
     */
    public function testFooException($paramBar, $paramBuz, $expectedException)
    {
        $myObject = new MyClass();
        $this->expectException($expectedException);
        $myObject->foo($paramBar, $paramBuz);
    }
    public function provideDataForFooException()
    {
        return [
            ['expected exception', 'bar invalid argument', '\My\Exception\Fully\Qualified\Name'],
        ];
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 扩展解决方案

一种。一种测试方法并使用反射API。

我们只有一种测试方法。数据提供程序方法返回一个数组,其中$expected测试方法输入的元素可以是Exceptions。如果$expected是 ,Exception我们用 处理这种情况expectException(...),否则作为“正常”测试用例。

湾 一种测试方法并使用“异常”标志。

理论上,一个方法可以returnException. 为了考虑这种情况,我们必须引入一个像“testItForException”这样的标志,并将此信息提供给测试方法。它也可以是另一个元素,例如exception,在由数据提供者方法返回的数组中(然后在测试方法中:)if(! (empty($exception)) { test it as normal } else {expect exception})