2

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

假设我们有 3 个类:

UserController
UserService
UserRepository

过去,我们会在 UserService 的方法中做这样的事情:

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

但是,由于没有注入对 SomeSession 的依赖,因此实际上不可能对此进行单元测试。但是,如果我们使用 DI 将依赖项注入到 UserService 中,则会话会在 UserService 的生命周期内挂起。如果有多个从 UserController 调用的服务,则每个服务都可能有会话,直到 UserController 被垃圾回收。

关于如何更好地管理这个的任何想法?我错过了一些明显的东西吗?

编辑

抱歉,如果我不清楚 - 我知道我可以将依赖注入与会话/数据上下文一起使用,但是它会在服务类的生命周期内得到维护。对于任何运行时间较长的操作/方法(例如,假设服务被批处理调用),除了增加可测试性之外,这可能会导致很多打开的会话。

4

2 回答 2

2

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

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

只有极少数情况下我使用真实连接进行单元测试,但这是针对我的存储库类的单元测试,而不是针对任何控制器、UI 或业务层对象的单元测试。

编辑:有了你添加的评论,我想我现在明白你的实际要求了。有趣的是你会问一些关于这个的问题,因为我上周研究了同样的主题:-)

我在一个非常薄的包装器中实例化数据上下文,并将上下文放入 HttpContext.Current.Items 字典中。这样,上下文是全局的,但仅适用于当前请求。

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

于 2009-08-10T10:21:16.327 回答
-2

最简单的方法是使用您在 web.config 中定义的用于开发和生产的 Connectionstring。对于单元测试,您在测试项目的 app.config 中定义它。

于 2009-08-10T10:02:30.107 回答