【问题标题】:mspec & rhino mocks expected exception testingmspec & rhino 模拟预期的异常测试
【发布时间】:2011-04-13 15:16:05
【问题描述】:

我对单元测试还很陌生,不知道如何正确测试(或者我什至应该)这个案例。

我有一个控制器方法(伪代码):

public ActionResult Register(formModel model)
{

    if (ModelState.isValid) {

        try {

            _userService.CreateUser(a bunch of parameters here);
            return RedirectToAction(some other action);
        }
        catch (Exception e)
        {

            ModelState.AddModelError("",e.Message);

        }

    }

    return View();
}

我有一堆针对“_userService”的单独测试。 “CreateUser”方法只是创建一个新用户并且不返回任何内容,或者如果出现错误(例如用户存在),我会在 try catch 中冒泡到控制器环绕并将异常添加到 ModelState。

据我了解,我应该模拟该服务并断言它被正确调用(我使用 assertwascall 语法),因为它什么也不返回,我只想知道我的控制器调用它。

我不确定如何测试当用户服务抛出错误时它不应该重定向并且应该将该异常添加到模型状态。使用 rhino 模拟,您可以对模拟进行存根,但单元测试的书籍艺术建议不要这样做。

现在在我的测试中,我手动添加了一个模型错误(不关心它是否来自用户服务)并测试控制器是否在出现错误时返回相同的视图。这是解决这个问题的正确方法吗?或者我应该创建一个单独的测试,在其中我存根 _userService 以引发错误并检查它是否被添加到模型状态?或者我什至不应该测试那个案例?我觉得我可能只是过度分析了整个事情,使用模型状态进行测试就足以满足这一点......

【问题讨论】:

    标签: unit-testing tdd rhino-mocks mspec


    【解决方案1】:

    您的模拟代表一个协作类。我不会太在意模拟和存根之间的区别。它仍然是一个协作类。

    您可以将单元测试视为描述如何使用您的类,以及该类如何与其协作者进行交互。你有两个例子:

    Given a controller
    When I register the model
    Then the class should ask the user service to create a user.
    

    还有:

    Given a controller
    Given the user service is broken
    When I register the model
    Then the class should attach the error to the model state.
    

    第二个Given 告诉你你是在存根而不是在嘲笑。您正在设置用户服务,就好像它已损坏一样。类作用的上下文不同,所以需要stub,确实应该抛出异常。

    如果您将这些行作为 cmets 放入您的测试中,那将是有意义的。如果有道理,请忽略这本书。

    顺便说一句,这是单元级 BDD。您可以在单元级别使用“Given, When, Then”,就像在场景级别一样,它可能会帮助您思考测试的逻辑。只是不要为此使用 BDD 场景工具。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-05
      • 2016-03-10
      • 1970-01-01
      相关资源
      最近更新 更多