【问题标题】:How to unit test asp.net mvc base controllers without hitting the database?如何在不访问数据库的情况下对 asp.net mvc 基本控制器进行单元测试?
【发布时间】:2009-03-26 00:09:38
【问题描述】:

我一直在使用“穷人”依赖注入技术对控制器进行单元测试。每个控制器都从基本控制器继承以查询母版页的数据。如何在不访问数据库的情况下对从基本控制器继承的控制器进行单元测试?

public class HomeController : BaseController
{
    IUserRepository _userRepository;

    public HomeController() : this(new UserRepository()) {

    }

    public HomeController(IUserRepository userRepository) {
        _userRepository = userRepository;
    }
}

public class BaseController : Controller
{
    protected override void Execute(System.Web.Routing.RequestContext requestContext)
    {
        MyDataContext db = new MyDataContext();

        ViewData["masterPageData"] = db.GetSomeData();

        base.Execute(requestContext);
    }
}

【问题讨论】:

  • 您能否提供更多信息,特别是“查询母版页数据”的代码在哪里?
  • 在父控制器的任何Action方法期间,代码都会从BaseController中的Execute方法调用。

标签: asp.net-mvc unit-testing


【解决方案1】:

代码看起来像这样:

public class HomeController : BaseController
{
    IUserRepository _userRepository;
    public HomeController() : this(new UserRepository()) { }
    public HomeController(IUserRepository userRepository) : base() {
        _userRepository = userRepository;
    }
    public HomeController(IUserRepository userRepository, ISomeRepository someRepository) : base(someRepository) {
        _userRepository = userRepository;
    }
}
public class BaseController : Controller
{
    ISomeRepository _someRepository;
    public BaseController(ISomeRepository someRepository)
    {
        _someRepository = someRepository;
    }
    public BaseController()
    {
        _someRepository = new SomeRepository();
    }
    protected override void Execute(System.Web.Routing.RequestContext requestContext)
    {
        MyDataContext db = new MyDataContext();
        ViewData["masterPageData"] = _someRepository.GetSomeData();
        base.Execute(requestContext);
    }
}

也就是说,如果您使用 DI 框架,则每个类中只需要 1 个构造函数。所以你可以看到它是如何开始倾向于使用一个的:)。

【讨论】:

    【解决方案2】:

    也许通过在你的 datacontext 上有一个接口并注入你的 datacontext 然后实现一个接口的模拟,它可以在不访问数据库的情况下返回数据

    【讨论】:

      【解决方案3】:

      我会说问题在于您的基本控制器使用不同的数据访问方法。此外,BaseController 硬连接到 DataContext,这会导致可测试性问题。

      如果 BaseController 需要从数据库中获取数据,为什么不使用存储库呢?如果完整的 IoC 容器不可用,您可以在继承的控制器中注入存储库依赖项并将其传递给 BaseController。

      这样很容易为母版页数据创建模拟。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多