我应该测试我的控制器(MVC)吗?

时间:2012-04-18 13:40:37

标签: model-view-controller controller mocking tdd integration-testing

我已经使用TDD几个月了,现在我想学习如何测试我的控制器(MVC)。

通过测试每个功能的最小单位来进行单元测试。有时,控制器不小。他们从模型中获取数据并传递给视图。

我应该如何对控制器进行单元测试?我应该模拟控制器的依赖吗?

控制器测试是否被视为集成测试?

谢谢。

4 个答案:

答案 0 :(得分:17)

我正在做TDD很长一段时间。我正在使用ASP.NET MVC进行TDD超过一年。

我从规范规则开始:“没有单元测试的代码行”,所以我测试了一切 - 包括控制器。必须对控制器进行测试,这是MVC框架的目标之一 - 使这些东西可以测试。

对于小型应用程序,该方法非常有效。几乎所有逻辑都放在控制器内部,一切都经过了很好的测试。

但只要我继续使用MVC,我就开始改变主意了。我尽量让控制器保持苗条。理想情况下,只需将调用委托给某个业务对象并包装结果。其余的是过滤器。

这对我也很有用!我现在拥有单独实现/测试的业务对象,因此控制器只是集成点。没有理由测试集成点,因为它很小。

关于集成测试:我还没有遇到过我实际需要的情况。不要忘记,控制器总是依赖于构造函数注入的抽象。只要您对这些抽象如何工作有“好”的假设,就可以创建适当的单元测试。当你失败时,你只需要更正单元测试。

集成测试非常重要且有用,但我尝试尽可能少地创建它们。

答案 1 :(得分:5)

我采用与Alexander B相同的控制器方法。我的控制器很薄而且笨。但是,我仍然为它们编写测试,以确保它们正确调用业务或服务对象并传递正确的参数。

这可能是我上周最终抓到的一个实际错误所能说明的。我有一个允许管理员批准或拒绝用户请求的控制器,它有两个视图,一个未完成请求的列表视图和每个请求的详细信息视图。两种观点都可以批准或否认。控制器调用的服务有一堆其他公开的方法,包括一个用于更改请求状态的方法......你可以看到它的发展方向。列表视图称为批准或拒绝并触发工作流的正确方法,详细信息视图仅调用更改状态方法,并且未启动任何进一步的工作流。这是我的编码错误,但对于我的生活我多年都看不到它 - 工作流在后台线程中运行,我花了一个星期的时间在这些线程中运行,假设它在该部分中是错误的。

所以对我来说

  • 一旦您的控制器将数据传递到其他地方,就需要进行测试。
  • 如果您的控制器检查模型有效性,则需要进行测试(如果 有人取消了支票吗?)

答案 2 :(得分:3)

昨天问了同样的问题:

Does it make sense to test controllers

在我看来 - 是的,测试控制器确实有意义。你可以:

  • 他们背后的模拟服务,因此更容易测试控制器本身
  • 保持服务不动,并进行集成测试

答案 3 :(得分:2)

要为您的控制器开发单元测试,自然的方法是模拟控制器所依赖的接口(它控制的“事物”,让我们称之为IControllable)。然后,您可以验证控制器是否以预期的方式操作受控对象。

如果控制器和受控对象之间的交互很复杂,那么专用的集成测试可能有意义。例如,可能有一系列实现IControllable的类 - 这些实现中的每一个都能很好地与控制器协同工作吗?也许多个不同的IControllables会互动(使用相同的资源)?或者IControllables可能有棘手的方法来配置它们影响他们的行为?测试这种方法的一种方法是编写一个可重复使用的测试套件,您可以在其中引入一系列可疑的IControllable实现或组合。

最后但同样重要的是,TDD也是关于验收测试。因此,在进行TDD时,您还将进行高级端到端测试,以执行最终用户可识别的方案。最有可能的是,它们也会运行控制器 - 这样也可以测试控制器和(某些)类之间的正确集成。