使用TDD设计MVC控制器进行数据库调用

时间:2018-04-24 15:29:20

标签: c# asp.net-mvc unit-testing tdd

我是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模型,这样当我进行单元测试时,我可以提供一个静态的位置列表作为返回值?

我不确定这应该如何正确构建。

1 个答案:

答案 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以将接口映射到实现并将其注入控制器。

参考ASP.NET MVC 4 Dependency Injection