【问题标题】:Controller Tests for Service Layer Logic服务层逻辑的控制器测试
【发布时间】:2011-12-15 09:30:06
【问题描述】:

我有一个具有以下架构 MVC 应用程序 > 服务 > 存储库的解决方案。现在假设我有一个文档模型,一个文档有很多注释。我有一个带有 AddNote(documentID) 操作的 Notes 控制器。现在我的业务规则说只有与文档关联的用户才能添加注释,所以我强制执行此操作。我目前正在使用以下方法:

public ActionResult AddNote(int documentID)
    {
        try
        {
            NoteCreateEditViewModel viewModel = Mapper.Map<Note, NoteCreateEditViewModel>(noteService.GetNewNote(User.Identity, documentID));
            return View(viewModel);
        }
        catch (BusinessLogicException validationException)
        {
            // Send user somewhere else.
        }
    }

noteService.GetNewNote(User.Identity, documentID) 如果用户对 Document 没有权限,则会引发 BusinessLogicException。我正在使用异常,因为这似乎是处理业务/验证违规的最佳方式(尽管我个人认为这是对异常的不好使用!)。

当从控制器测试中测试上述内容时,我应该只是测试如果抛出 BusinessLogicException 会发生正确的重定向(或其他),还是应该模拟未经授权的用户/不存在的 documentID 等?在我看来,GetNewNote(User.Identity, documentID) 的服务测试将是模拟未经授权的用户的地方,因为这可以确保我的测试正在测试特定代码的核心功能。

但是,如果我不编写模拟未经授权的用户生成异常的控制器测试,那么将来查看我的测试的人将如何理解 AddNote 所需的功能是防止未经授权的用户添加注释。如果他们不理解这一点,他们可能会想直接在控制器中简单地初始化一个新 Note,而不是通过 noteService.GetNewNote(User.Identity, documentID)。

那么我应该在我的控制器中进行更多测试,还是在添加关联模型方面有更简单的设计?

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 unit-testing


    【解决方案1】:

    在您的单元测试中,您应该模拟noteService.GetNewNote 方法调用,以便它抛出BusinessLogicException。然后断言控制器操作返回了重定向结果。

    【讨论】:

    • 但是我的控制器测试不会明确说明用户必须有权访问指定的文档。因此,将来维护应用程序的任何人都不会意识到通过服务创建新便笺比直接在控制器中创建新便笺的重要性 - 如果他们进行此更改,则不会中断任何测试,但绕过了所需的业务逻辑。
    • 也许我只是想多了。 noteService.GetNewNote 方法在控制器测试中被模拟的事实应该提醒其他开发人员需要服务层来创建 Notes。但不能确保实际调用了该方法。有没有办法做到这一点,测试一个方法是用 MSTest 调用的?
    • 我肯定想多了!断言正在检查是否引发了异常。如果另一个开发人员避免调用 noteService.GetNewNote,则不会发生异常并且测试失败,迫使他们进一步调查并了解该过程。呸!这个问题几乎变成了一个独白,但我最终到达了那里。谢谢达林。
    猜你喜欢
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-05
    • 1970-01-01
    • 2015-01-08
    • 2017-06-03
    • 2012-03-14
    相关资源
    最近更新 更多