如何在 PHPUnit 中使用数据提供程序测试异常?
How to test exceptions using a data provider in PHPUnit?
PHPUnit 有一个非常有用的功能 @dataProvider
, that allows to test multiple cases of a method. It also has another cool annotation -- @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
?
PHPUnit 不提供这种组合。但这可以通过一个简单的技巧来实现:
- 基本解
正常和异常测试的独立测试方法。
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'],
];
}
}
- 扩展解决方案
一个。一种测试方法并使用ReflectionAPI.
我们只有一种测试方法。数据提供者方法 returns 一个数组,其中 $expected
测试方法输入的元素可以是 Exceptions
。如果 $expected
是 Exception
我们用 expectException(...)
处理这种情况,否则作为 "normal" 测试用例。
b。一种测试方法并使用 "exception" 标志。
理论上一个方法可以return
一个Exception
。考虑到这种情况,我们必须引入一个标志,如 "testItForException" 并将此信息提供给测试方法。它也可以是另一个元素,例如exception
,在数据提供者方法返回的数组中(然后在测试方法中:if(! (empty($exception)) { test it as normal } else {expect exception})
)。
除了注释,您还可以使用带有参数的 $this->setExpectedExceptionRegExp()
$exceptionName — mixed (class name or exception instance)
$exceptionMessageRegExp — string (optional regular expression)
$exceptionCode — integer (optional exception code)
注意:旧的setExpectedException()
方法在PHPUnit 5.2
中已弃用
这意味着,您可以通过数据提供程序传递异常 class 名称。如果不为空,调用setExpectedExceptionRegExp()
该方法相对于注释的另一个优点是,如果您不在注释的开头调用该方法,您可以更具体地说明哪里会出现异常测试。
PHPUnit 有一个非常有用的功能 @dataProvider
, that allows to test multiple cases of a method. It also has another cool annotation -- @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
?
PHPUnit 不提供这种组合。但这可以通过一个简单的技巧来实现:
- 基本解
正常和异常测试的独立测试方法。
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'],
];
}
}
- 扩展解决方案
一个。一种测试方法并使用ReflectionAPI.
我们只有一种测试方法。数据提供者方法 returns 一个数组,其中 $expected
测试方法输入的元素可以是 Exceptions
。如果 $expected
是 Exception
我们用 expectException(...)
处理这种情况,否则作为 "normal" 测试用例。
b。一种测试方法并使用 "exception" 标志。
理论上一个方法可以return
一个Exception
。考虑到这种情况,我们必须引入一个标志,如 "testItForException" 并将此信息提供给测试方法。它也可以是另一个元素,例如exception
,在数据提供者方法返回的数组中(然后在测试方法中:if(! (empty($exception)) { test it as normal } else {expect exception})
)。
除了注释,您还可以使用带有参数的 $this->setExpectedExceptionRegExp()
$exceptionName — mixed (class name or exception instance)
$exceptionMessageRegExp — string (optional regular expression)
$exceptionCode — integer (optional exception code)
注意:旧的setExpectedException()
方法在PHPUnit 5.2
这意味着,您可以通过数据提供程序传递异常 class 名称。如果不为空,调用setExpectedExceptionRegExp()
该方法相对于注释的另一个优点是,如果您不在注释的开头调用该方法,您可以更具体地说明哪里会出现异常测试。