简体   繁体   English

PHPUnit代码覆盖率和异常

[英]PHPUnit Code Coverage & Exceptions

I suspect PHPUnit is showing that 1 line of code is not covered by unit tests because of exceptions thats thrown (but I caught) 我怀疑PHPUnit显示由于抛出了异常,所以单元测试未覆盖1行代码(但我抓住了)

I have unit test that should cover that line 我有应该覆盖那条线的单元测试

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

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

}

Why is my code coverage still reflecting that is not covered? 为什么我的代码覆盖率仍反映未覆盖的内容?

I did a test ... added echo b4 returning null ... I found that that line is really not covered ... 我做了一个测试...添加了回显b4返回null ...我发现该行确实未被覆盖...

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

Is PHPUnit skipping all execution once an exception is thrown? 一旦抛出异常,PHPUnit是否会跳过所有执行?

UPDATE : I got a feeling that I am using @expectedException wrong tho ... 更新 :我感觉我在使用@expectedException错误...

Your code samples are just the tip of the iceberg, its hard to pinpoint the exact problem. 您的代码示例只是冰山一角,很难确定确切的问题。

But one detail seems suspicious to me: given that your login method is in the Application\\Models then, the following code 但是一个细节对我来说似乎很可疑:鉴于您的登录方法位于Application \\ Models中,因此以下代码

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

will not catch any exception, it would catch \\Application\\Models\\Exception - if you even have such a class defined. 不会捕获任何异常,而是会捕获\\ Application \\ Models \\ Exception-如果您甚至定义了此类。

Maybe that is the reason why your exception handler does not run. 也许这就是您的异常处理程序无法运行的原因。

The @expectedException Annotation is similar to this testcode: @expectedException Annotation类似于以下测试代码:

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

so you can not (should not) test two things at once in that Testcase. 因此,您不能(不应)在该测试用例中一次测试两件事。 (If the exception is thrown AND the return value) (如果抛出异常并返回值)

If you want to test that User::login throws an exception you are good to go for that testcase and the assertion isn't needed (that code isn't executed anyways :) ) 如果您想测试User::login引发异常,则最好使用该测试用例,并且不需要断言(无论如何也不会执行该代码:))

To get the red line covered you'd need to write code so $query->getSingleResult() throws an exception. get the red line covered您需要编写代码,以便$ query-> getSingleResult()引发异常。 That could be tricky but since i don't see enough of the source (like where the query object is coming from) i can't be specific here. 这可能很棘手,但由于我没有看到足够多的源(例如查询对象来自何处),因此我在这里无法具体说明。

If the $query object is a mock let it throw an exception on ->getSingleResult and write testcase checking for "null" 如果$ query对象是模拟对象,则让它在-> getSingleResult上引发异常,并编写测试用例以检查是否为“ null”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM