单元测试和SRP(测试方法范围/组织)

问题描述:

说我有一个MVC的行动,比如:单元测试和SRP(测试方法范围/组织)

public ActionResult CustomerRecord(customerId) 
{ 
    if (_currentUser.CanViewCustomer(customerId)) 
     return View(); 

    else 
    { 
     // user has tried to access an unauthorised record, 
     // should not be here! 
     _logger.Log(new SecurityException()); 
     return View("UnauthorizedAccess"); 
    } 
} 

要测试的未授权访问尝试的情况下,有多少测试方法应该有?

即做我写一个测试:

CustomerRecord_WithUnauthorizedUser_LogsExceptionAndReturnsUnauthorizedView 

还是我写两个测试:

CustomerRecord_WithUnauthorizedUser_LogsException 
CustomerRecord_WithUnauthorizedUser_ReturnsUnauthorizedView 

我想这个问题是在技术上控制器违反SRP,但我不看到它本身就是一个问题(如果你不同意,请纠正我)。我只是不确定如何映射到测试方法。该方法的每个责任的一个测试,或者通过该方法的每个单一路线的一个测试?

您的控制器并不一定是做了两件事违反 SRP - 它仍然只得到了一个责任(控制)。

在这个具体的例子,我奉劝不要断言日志调用时 - 它不会,如果你拿出日志语句影响你的应用程序的功能。过度指定单元测试会让它们变得脆弱而且难以维护,这也是我非常喜欢BDD的原因之一。

如果你不得不审计每一个失败的尝试之后我想这是值得的单元测试,所以如果这是你在做什么,然后阅读:

一般情况下,你应该只有一个断言(也许你倒是有每单元测试调用断言方法或两个做一个语义断言) - 主要是因为它很高兴能看到失败的测试的名称,并确切地知道什么出了问题,而无需看代码。所以我主张有两个测试......

+0

“你的控制器并不一定是做两件事情违反SRP - 它仍然只得到了一个责任(控制)” 恐怕,这是责任的非常模糊的定义。你如何定义控制责任?如果你问5个程序员这个问题,恐怕你会得到5个不同的答案。与名为Manager的类相同。 –

我喜欢每测试一个断言(或责任,你把它),因为它立即变得很清晰了代码路径的一部分已经失败,如果有一个问题。这假设你在阅读测试结果时以一种可以理解的方式命名你的测试(你的例子)。