如何对Linq2SQL进行可测试性抽象



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

作为我正在做的工作的一部分,我正在尝试测试各种组件,以引入一些稳定性。清理代码库,它目前大量使用静态类和方法,控制器具有贯穿始终的静态DataContext。

如何重构L2S的使用,以便测试控制器的操作?

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

我尝试过的一件事是利用L2S生成的分部类,并向DataContexts添加了一个Interface,但我发现抽象会一直渗透到应用程序中,而不是停留在类库中。这感觉不像是正确的做事方式,维持下去会很痛苦。有人用这种方法取得过特别的成功或失败吗?

我使用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

虽然本文提到了使用实体框架的可测试性,但这里可以应用高级概念。

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

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

最新更新