2010-12-18 125 views
5

我怀疑PHPUnit的是示出了1行的代码没有覆盖因为异常的单元测试这就是甩(但我抓住)PHPUnit的代码覆盖率和异常

我已经单元测试应该覆盖该行

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

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

} 

为什么我的代码覆盖率仍然反映,没有涵盖?

我做了一个试验...添加回声B4返回null ......我发现,该行确实不是盖的......

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

是PHPUnit的跳过所有执行一次抛出一个异常?

更新:我得到了我使用@expectedException错误寿的感觉...

+0

是您在命名空间里“登录”的方法? – 2010-12-19 10:01:18

+0

@Anti Veeranna,是的,它在'Application \ Models'中。它在名称空间中是否会改变任何内容? – 2010-12-19 11:54:19

回答

4

你的代码示例是冰山的一角,它很难确定确切的问题。

但一个细节看似可疑的对我说:因为你的登录方法是在应用程序\型号的话,下面的代码

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

不会捕捉任何异常,它会赶上\应用\型号\异常 - 如果你甚至有这样的类定义。

也许这就是你的异常处理程序不运行的原因。

+1

除非我弄错了,否则解决方法是将异常类更改为'\ Exception',以便捕获所有异常类型。 – 2011-11-08 21:59:39

2

@expectedException注释与此类似testcode:

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

所以你不能(也不应该)测试在这一次测试用例两件事情。 (如果抛出异常并返回值)

如果你想测试一下User::login会抛出一个异常,那么你最好去那个测试用例并且不需要断言(该代码不会被执行:) )

get the red line covered您需要编写代码,以便$ query-> getSingleResult()引发异常。这可能会很棘手,但由于我没有看到足够的源代码(例如查询对象来自何处),因此我无法在此处详细说明。

如果$查询对象是一个模拟让它扔在一个异常 - > getSingleResult写测试用例检查“空”