c# - 如何对使用 Servicestack Funq IOC 的 DBService 进行单元测试

标签 c# unit-testing mocking ormlite-servicestack servicestack-ioc

我是一个需要扩展的项目的新手,因此我决定使用 TDD 来快速识别我不完全理解的系统的任何问题。

有一个名为DBService的类,它“封装”了所有数据库访问。例如,有一个名为 getAllCustomers 的方法,它返回 Customers 列表。这看起来像这样(这只是为了更好地理解的一个例子):

public class DBService
{
    public IDbConnectionFactory DBFactory { 
        get { return DI.Container.Resolve<IDbConnectionFactory>(); }
    }

    public List<Customer> GetAllCustomers()
    {
        try
        {
            using (var connection = DBFactory.OpenDbConnection())
            {
                var dbResult = connection.Select<Customer>();
                // code ommitted
            }
        }
        catch (Exception e)
        {
            // code ommitted
        }
    }      
}

另一个问题是,在启动时(在 ServiceStack AppHost.Configure 中),如果表不存在,则会创建所有表,并且对于某些表,如果存在,则会添加一些列等(可能是稍后添加的更改)

例如,当我现在必须扩展客户并添加另一个字段、地址时,我想以 TDD 风格执行此操作,但我不知道如何操作。

  1. 我无法注入(inject)任何DBFactory,因为 getter 是私有(private)的
  2. 据我所知,我无法对 OrmLiteConnectionFactory 使用 :memory: 连接字符串,因为我使用的是 ServiceStack 3.9.74

那么我有什么选择?

最佳答案

避免服务定位器反模式并使用构造函数注入(inject)。尽量避免在依赖类中直接使用 DI 容器。它将您的类与不属于该类的关注点紧密耦合在一起,并使单独测试类变得困难。

public class DBService {
    private readonly IDbConnectionFactory connectionFactory;

    public DBService(IDbConnectionFactory connectionFactory) {
        this.connectionFactory = connectionFactory;
    }

    public IDbConnectionFactory DBFactory { get { return connectionFactory; } }

    public List<Customer> GetAllCustomers() {
        try {
            using (var connection = DBFactory.OpenDbConnection()) {
                var dbResult = connection.Select<Customer>();
                //... code omitted for brevity
            }
        } catch (Exception e) {
            //... code omitted for brevity
        }
    }
}

两者Select<T>OpenDbConnection看起来像扩展方法。我建议检查他们的期望是什么,并 mock 这些行为。

如果DbService本身要用作其他类的依赖项,那么该类也应该被抽象。

public interface IDbService {
    IDbConnectionFactory DBFactory { get; }
    List<Customer> GetAllCustomers();
}

并让实现继承

public class DbService : IDbService { 
    //... code removed for brevity
}

并确保向 IoC 容器注册所有内容。

关于c# - 如何对使用 Servicestack Funq IOC 的 DBService 进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41957605/

相关文章:

python - Flask 蓝图单元测试

ruby-on-rails - 测试时按特定顺序加载 Rails fixture

c# - 如何创建没有 GUI 的 C# 程序?

c# - Devexpress Winforms 数据 GridView : Deactivate "Drag Column Header here to group by that column"-Option

c# - 如何使用 Roslyn 读取 XML 文档注释

javascript - QUnit 模拟自动完成

c# - .NET 正则表达式中的 (?i) 是什么意思?

python - 模拟文件在python中打开

java - jOOQ:模拟 DAO 对象

python - 如何模拟 os.listdir 以假装 Python 中的文件和目录?