PHPUnit代码覆盖率&例外

时间:2010-12-18 07:39:23

标签: php exception phpunit

我怀疑PHPUnit显示单行测试不包含1行代码,因为抛出的异常(但我抓住了)

我的单元测试应该涵盖那一行

/**
 * @expectedException Doctrine\ORM\NoResultException
 */
public function testCannotLoginInvalidUser() {

  $user = User::login($this->em, 'nonExistant', 'password');
  $this->assertNull($user);

}

为什么我的代码覆盖率仍然反映不包括在内?

我做了一个测试...添加echo b4返回null ...我发现那行真的没有被覆盖......

try {
  $user = $query->getSingleResult();
} catch (Exception $e) {
  echo 'caught exception';  <-- this does not get executed. 
  return null;
}

一旦抛出异常,PHPUnit是否会跳过所有执行?

更新 :我觉得我错误地使用了@expectedException ......

2 个答案:

答案 0 :(得分:4)

您的代码示例只是冰山一角,难以确定问题所在。

但是有一个细节对我来说似乎很可疑:假设你的登录方法在Application \ Models中,那么下面的代码

try {
  $user = $query->getSingleResult();
} catch (Exception $e) {

不会捕获任何异常,它会捕获\ Application \ Models \ Exception - 如果你甚至定义了这样的类。

也许这就是您的异常处理程序无法运行的原因。

答案 1 :(得分:2)

@expectedException注释类似于此测试代码:

public function testDoStuff() {
    try { 
        doStuff();
    } catch(Exception $e) {
        // Test passed
        return;
    }
    $this->fail("Exception not thrown, test failed !");
}

所以你不能(不应该)在Testcase中同时测试两件事。 (如果抛出异常并返回值)

如果你想测试User::login抛出一个异常,你就可以使用那个测试用例并且不需要断言(该代码不会被执行:))

get the red line covered,您需要编写代码,以便$ query-&gt; getSingleResult()抛出异常。这可能是棘手的,但因为我没有看到足够的源(如查询对象的来源),我不能在这里具体说明。

如果$ query对象是mock,则让它在 - &gt; getSingleResult上抛出异常,并写testcase检查“null”