代码之家  ›  专栏  ›  技术社区  ›  Beep beep

在哪里实例化MVC中的数据上下文(适配器、连接、会话等)?

  •  2
  • Beep beep  · 技术社区  · 16 年前

    我们正在构建一个ASP.NET MVC站点,我正在努力定义一个连接以实现最佳的单元测试(我一般使用“连接”——它可以是会话、连接、适配器或任何其他类型的数据上下文,可以管理事务和数据库操作)。

    假设我们有3个班:

    UserController
    UserService
    UserRepository
    

    在过去,我们会在用户服务的方法中执行类似的操作:

    Using (ISomeSession session = new SomeSession())
    {
      session.StartTransaction();
      IUserRepository rep = new UserRepository(session);
      rep.DoSomething();
      rep.Save();
      session.Commit();
    }
    

    但是,由于没有注入对某个会话的依赖性,因此不可能进行单元测试。但是,如果我们使用d.i.在用户服务中注入依赖项,那么会话将在用户服务的生命周期中一直挂起。如果从UserController调用了多个服务,那么每个服务都可能有会话挂起,直到对UserController进行垃圾收集。

    有什么关于如何更好地管理这个的想法吗?我是否遗漏了一些明显的东西?

    编辑

    抱歉,如果我不清楚的话-我理解我可以在会话/数据上下文中使用依赖注入,但是在服务类的整个生命周期中都在维护它。对于任何长时间运行的操作/方法(例如,假设服务正由批处理过程调用),这可能导致大量的开放会话,除了添加可测试性之外,没有其他原因。

    2 回复  |  直到 16 年前
        1
  •  2
  •   Adrian Grigore    16 年前

    正如Richardod正确观察到的,您不能使用实时数据库连接来编写单元测试。如果您正在这样做,那么您就是集成测试。

    我为我的存储库接口、一个真正的存储库和一个用于单元测试的假存储库提供了单独的实现。假存储库在通用列表上工作,而不是实际的数据上下文。我正在使用DI(与Ninject一起使用以使事情更为舒适,但您也可以手工完成)来注入正确的存储库。

    在只有很少的实例中,我使用实际连接进行单元测试,但这是我的存储库类的单元测试,而不是任何控制器、UI或业务层对象的单元测试。

    编辑: 加上你的评论,我想我现在明白你到底在要求什么了。有趣的是,你会问一些关于这方面的问题,因为我上周研究的是同一个主题:—)

    我在一个非常薄的包装器中实例化数据上下文,并将其放入httpContext.current.items字典中。这样,上下文是全局的,但只针对当前请求。

    不过,你的问题的主题是高度误导性的。您在问“在哪里为单元测试实例化数据上下文”,答案是您通常不会这样做。我的单元测试仍然在假存储库上运行。

        2
  •  -2
  •   Mathias F    16 年前

    最简单的方法是使用在web.config中为开发和生产定义的连接字符串。对于UnitTests,您可以在测试项目的app.config中定义它。