如何抽象Linq2SQL的可测试性

时间:2012-03-31 11:45:21

标签: asp.net-mvc unit-testing linq-to-sql testability

我正在开发一个使用Linq2SQL进行数据访问的项目。该项目由ASP.NET MVC应用程序和8个类库组成。大多数类库都有自己的L2S数据类。

作为我正在做的工作的一部分,我正在尝试将各种组件置于测试中以引入一些稳定性来清理代码库,它目前大量使用静态类和方法,并且控制器具有静态DataContexts在整个过程中使用。

如何重构L2S用法以便我可以测试控制器操作?

我已经在应用程序中引入了依赖注入来解耦其他一些服务但我不希望DataContext作为控制器的依赖属性,因为我想控制DataContexts及其DataLoadOptions的实例化。

我尝试过的一件事是利用L2S生成的部分类,并为DataContexts添加了一个接口,但我发现抽象冒出了它进入应用程序而不是停留在类库中。它不像是正确的做事方式,维持是一种痛苦。有没有人用这种方法有任何特别的成功或失败?

2 个答案:

答案 0 :(得分:3)

我使用Repository模式隐藏DataContext。存储库是抽象的,所以套件非常适合依赖注入原则。

例如,您定义了一些存储库。

public interface IUserRepository
{
    User Get(int id);
    User Save(User user);
    void Delete(User user);
}

实现类似于

public class UserRepository : IUserRepository
{
    private MyDataContext _context;

    UserRepository() 
    {
        _context = new MyDataContext();
    }

   // ...

}

现在,控制器仅依赖于接口。

public UserController : Controller
{
    UserController(IUserRepository userRepository) { }
}

所以,它完全可以测试,因为你可以在测试中模拟IUserRepository

答案 1 :(得分:1)

虽然this article指的是使用实体框架的可测试性,但可以在此处应用高级概念。

示例的核心是使用“工作单元”模式和“存储库”模式。工作单元是围绕数据上下文的抽象,表示特定控制器或一组类似控制器的工作集。您可以在单元中包含多个存储库,并且由于存储库基于IEnumerableIQueryable,您仍然可以利用LINQ功能。

可测试性选项包括模拟单元和存储库,或创建用于测试目的的内存中表示。