关于php:用phpunit测试异常

testing exceptions with phpunit

当我知道错误时,我正试图测试一个函数。 该函数看起来像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
function testSetAdsData_dataIsNull(){
    $dataArr = null;
    $fixture = new AdGroup();

        try{
            $fixture->setAdsData($dataArr);
        } catch (Exception $e){
            $this->assertEquals($e->getCode(), 2);
        }

    $this->assertEmpty($fixture->ads);
    $this->assertEmpty($fixture->adIds);
}

现在我试图使用phpunit异常断言方法来替换try catch部分,但我无法弄清楚如何做到这一点。
我做了很多阅读,包括这篇文章PHPUnit断言抛出异常? 但我真的不明白它是如何实施的。

我试过这样的事情:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
 * @expectedException dataIsNull

 */


function testSetAdsData_dataIsNull(){
    $dataArr = null;
    $fixture = new AdGroup();

    $this->setExpectedException('dataIsNull');
    $fixture->setAdsData($dataArr);
    $this->assertEmpty($fixture->ads);
    $this->assertEmpty($fixture->adIds);
}

but obviously it didn't work  and i got this error:
1) adGroupTest::testSetAdsData_dataIsNull
ReflectionException: Class dataIsNull does not exist

我做错了什么,如果抛出异常,我怎么断言?


对于这种情况,我通常使用@expectedException注释。 在此处查看所有与异常相关的注释:

1
2
3
4
5
6
7
8
9
10
11
/**
 * @expectedException \Exception
 * @expectedExceptionCode 2
 */

function testSetAdsData_dataIsNull()
{
    $dataArr = null;
    $fixture = new AdGroup();

    $fixture->setAdsData($dataArr);
}

检查$fixture->ads实际上是否为null并不会真正添加到此处,您可以在实际触发异常的调用之前添加这些断言:

1
2
$this->assertNull($fixture->ads);
$fixture->setAdsData($dataArr);//throws exception

你是单元测试。 此测试有一个明确的目的:它确保在给定情况下抛出异常。 如果是,那就是测试结束的地方。

不过,如果你想保留那些assertEmpty电话,你可以这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
try {
    $fixture->setAdsData($dataArr);
    $e = null;
} cathc (Exception $e) {}
$this->assertEmpty($fixture->ads);
$this->assertEmpty($fixture->adIds);
if (!$e instanceof \Exception) {
    //if the exception is not thát important:
    $this->markTestIncomplete('No Exception thrown');
    //do other stuff here... possibly
    $this->fail('The exception was not thrown');
}
throw $e;//throw exception a bit later

另一种方法是手动调用$this->setExpectedException,如此处所述。 由于我们似乎不知道/关心异常消息的样子,我将使用setExpectedExceptionRegExp方法:

1
2
3
4
5
6
$fixture = new AdGroup();
$this->setExpectedExceptionRegExp(
    //exception class, message regex, exception code
    'Exception', '/.*/'. 2
);
$fixture->setAdsData(null);//passing null seems to be what you're doing anyway