【问题标题】:unit testing and SRP (test method scope/organisation)单元测试和 SRP(测试方法范围/组织)
【发布时间】:2011-07-29 11:21:30
【问题描述】:

假设我有一个 MVC 操作,例如:

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,但我不认为这本身就是一个问题(如果您不同意,请纠正我)。我只是不确定这如何映射到测试方法。每个方法的职责一个测试,还是通过该方法的每个单一路径一个测试?

【问题讨论】:

    标签: asp.net-mvc unit-testing tdd single-responsibility-principle


    【解决方案1】:

    您的控制器不一定通过做两件事来违反 SRP - 它仍然只有一个责任(控制)。

    在这个具体的例子中,我会提醒不要断言进行了日志调用——如果你取出日志语句,它不会影响你的应用程序的功能。过度指定单元测试会使它们变得脆弱且难以维护,这也是我如此喜欢 BDD 的部分原因。

    如果您必须审核每次失败的尝试,那么我想这值得进行单元测试,所以如果您正在这样做,请继续阅读:

    一般来说,每个单元测试你应该只有一个断言(也许你必须调用一个或两个 Assert 方法来做出一个语义断言)——基本上是因为能够查看失败的名称是很好的测试并准确知道出了什么问题,而无需查看代码。所以我主张进行两次测试...

    【讨论】:

    • “您的控制器不一定通过做两件事来违反 SRP - 它仍然只有一个责任(控制)” 恐怕这是对责任的非常模糊的定义。你如何定义控制的责任?如果你问 5 个程序员这个问题,恐怕你会得到 5 个不同的答案。与名为 Manager 的类相同。
    【解决方案2】:

    我更喜欢每次测试一个断言(或您所说的责任),因为如果出现问题,它可以立即清楚代码路径的哪一部分失败。这假设您以在阅读测试结果时可以理解的方式命名您的测试(您的示例)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-25
      • 1970-01-01
      • 2011-07-06
      • 2012-05-08
      • 2016-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多