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

时间:2016-09-14 09:15:19

标签: php unit-testing phpunit

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'],
        ];
    }
}

可能/如何使用@expectedException作为其中一种情况,使用@dataProvider

2 个答案:

答案 0 :(得分:3)

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

  1. 基本解决方案
  2. 正常和异常测试的单独测试方法。

    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'],
            ];
        }
    }
    
    1. 扩展解决方案
    2. 一个。一种测试方法并使用getMap() is deprecated API。

      我们只有一种测试方法。数据提供程序方法返回一个数组,$expected测试方法输入的元素的位置可以是Exceptions。如果$expectedException,我们会使用expectException(...)处理此情况,否则将作为"正常"测试用例。

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

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

答案 1 :(得分:2)

您也可以将$this->setExpectedExceptionRegExp()与参数

一起使用,而不是注释
$exceptionName — mixed (class name or exception instance)
$exceptionMessageRegExp — string (optional regular expression)
$exceptionCode — integer (optional exception code)

注意:旧的setExpectedException()方法已在PHPUnit 5.2中弃用

这意味着,您可以通过数据提供程序传递异常类名称。如果不为空,请致电setExpectedExceptionRegExp()

该方法相对于注释的另一个优点是,如果您不在测试开始时调用该方法,则可以更加具体地了解 预期的异常。< / p>