在构建我最新的 ASP.NET MVC 项目时,我开始涉足单元测试、依赖注入(inject)和所有爵士乐。
我现在想对我的 Controller 进行单元测试,但我很难弄清楚如何在没有 IoC 容器的情况下适本地做到这一点。
以一个简单的 Controller 为例:
public class QuestionsController : ControllerBase
{
private IQuestionsRepository _repository = new SqlQuestionsRepository();
// ... Continue with various controller actions
}
由于它直接实例化了 SqlQuestionsRepository,因此该类不是非常可单元测试的。因此,让我们走下依赖注入(inject)路线并执行以下操作:
public class QuestionsController : ControllerBase
{
private IQuestionsRepository _repository;
public QuestionsController(IQuestionsRepository repository)
{
_repository = repository;
}
}
这似乎更好。我现在可以使用模拟 IQuestionsRepository 轻松编写单元测试。但是,现在要实例化 Controller 的是什么?在调用链更上层的某个地方 SqlQuestionRepository 将不得不被实例化。似乎我只是将问题转移到其他地方,而不是摆脱它。
现在,我知道这是一个很好的例子,说明 IoC 容器可以通过为我连接 Controller 依赖项来帮助您,同时使我的 Controller 易于进行单元测试。
我的问题是,如何在没有 IoC 容器的情况下对这种性质的事物进行单元测试?
注意:我并不反对 IoC 容器,而且我可能很快就会走上这条路。但是,我很好奇不使用它们的人有什么替代方案。
最佳答案
难道不能保持字段的直接实例化并提供setter吗?在这种情况下,您只会在单元测试期间调用 setter。像这样的东西:
public class QuestionsController : ControllerBase
{
private IQuestionsRepository _repository = new SqlQuestionsRepository();
// Really only called during unit testing...
public QuestionsController(IQuestionsRepository repository)
{
_repository = repository;
}
}
我对 .NET 不太熟悉,但作为 Java 的旁注,这是重构现有代码以提高可测试性的常用方法。即,如果您有已经在使用的类并且需要修改它们以提高代码覆盖率而不破坏现有功能。
我们团队之前也这样做过,通常我们将 setter 的可见性设置为 package-private 并保持测试类的包相同,以便它可以调用 setter。
关于asp.net-mvc - 在没有 IoC 容器的情况下如何对 Controller 进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1041919/