我是MVC和单元测试的新手。我需要在我的控制器上进行单元测试,但我担心我可能没有正确设置它们。
例如:
public class MyController
{
public ActionResult Index(int id)
{
var locations = new MyLocations().GetLocations();
//linq code here that filters based on id
return View(filteredLocations)
}
}
这是一个非常简单的例子,但是如何正确设置它以便我可以使用TDD模型,这样当我进行单元测试时,我可以提供一个静态的位置列表作为返回值?
我不确定这应该如何正确构建。
答案 0 :(得分:0)
由于new MyLocations()
而导致的紧耦合意味着你无法操纵它的行为。
创建依赖的抽象
public interface ILocations {
IEnumerable<Location> GetLocations();
}
实现派生自抽象
public class MyLocations : ILocations {
public IEnumerable<Location> GetLocations() {
//...db calls here
}
}
和重构控制器依赖于抽象
public class MyController : Controller {
private readonly ILocations myLocations;
public MyController(ILocations myLocations) {
this.myLocations = myLocations;
}
public ActionResult Index(int id) {
var locations = myLocations.GetLocations();
//linq code here that filters based on id
return View(filteredLocations);
}
}
控制器现在是可测试的,因为当通过模拟框架或继承进行单独测试时,可以将替代注入控制器。
在生产中,您将配置DependencyResolver
以将接口映射到实现并将其注入控制器。