首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单元测试难题: OleDbCommand

单元测试难题: OleDbCommand
EN

Stack Overflow用户
提问于 2016-02-22 10:59:10
回答 2查看 716关注 0票数 1

我尝试进行单元测试的类之一是使用OleDbConnection对象。此对象负责根据传递的SQL字符串返回MS Access文件中保存的信息。守则是:

代码语言:javascript
复制
public void getInformation(DateTime start, DateTime finish)
{
    string getInfo = "";
    string query = "//Query for MS Access goes here";
    transactions = addTransactions(query, conn);
}

其中,addTransactions是一个私有方法,它返回从数据库检索的列表:

代码语言:javascript
复制
private List<string> addTransactions(string query, OleDbConnection conn)
{
    List<string> returnedData = new List<string>();
    OleDbCommand cmd = new OleDbCommand(query, conn);
    try
    {
        if (conn.State == ConnectionState.Closed) conn.Open();
        OleDbDataReader reader = cmd.ExecuteReader();
        while (reader.Read())
        {
            if (!reader.IsDBNull(0))
        }
        returnedData.Add(reader.GetString(0));
    }
    catch (Exception ex)
    {
        Console.WriteLine("OLEB: {0}", ex.Message);
    }
    conn.Close();
    return returnedData;
}

现在,通过查看这个方法,我已经知道单元测试将是困难的,因为公共getInformation()方法是无效的。我所能做的就是测试返回的数据中是否包含一些内容。我的问题是如何编写涉及OleDbConnection的单元测试?

我想到的唯一两个可能的解决方案要么是创建一个临时访问文件(因为我们现在超出了单元测试的范围,再加上测试在其他开发人员的机器上运行时有可能失败),要么是为OleDbConnection创建一个包装器,然后在单元测试中使用它(这听起来是最好的方法,但我不知道从哪里开始)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-22 11:13:28

或者为OleDbConnection创建一个包装器,并在单元测试中使用它。

这就是我的方法。不能直接模拟/可测试的对象通常表示自身的依赖关系。并且应该提供所有依赖项,而不是在内部实例化。

包装器可以是一个简单的传递,提供相同的功能。让它由接口和该接口的代码驱动,这样您就可以为该接口提供模拟,以便进行单元测试。(另一个额外的好处是,即使被测试的方法返回void,模拟也会给您提供一些可以观察的东西。因此,您不必在测试的系统中钻得太深,只需观察在模拟上调用了什么。)

从您正在嘲弄的内容的聚合根开始,您需要包装OleDbConnection。一个简单的入门示例如下所示:

代码语言:javascript
复制
public interface IDbConnection
{
    IDbCommand CreateCommand();
    // other methods
}

public class MyOleDbConnection : IDbConnection
{
    private OleDbConnection conn;

    public MyOleDbConnection()
    {
        // initialize "conn" here
    }

    public IDbCommand CreateCommand()
    {
        return conn.CreateCommand();
    }

    // other pass-thru methods
}

本质上,它只是一个由底层对象公开的相同功能的传递包装器。这样做的好处是,这个对象实际上不需要经过单元测试,因为它不包含任何有意义的可测试逻辑。(当然,获得100%的回报会很好,但这类产品的投资回报并不存在。)

正如您所看到的,这还涉及以类似的方式为OleDbCommand创建一个包装器。再一次,就是传递方法。

一旦您将依赖项包装好并可以模拟,就可以将类更改为使用包装器。例如,而不是这样:

代码语言:javascript
复制
OleDbCommand cmd = new OleDbCommand(query, conn);

它在内部保存对依赖项的引用,您可以这样做:

代码语言:javascript
复制
IDbCommand cmd = conn.CreateCommand();

它要求依赖项来引用某物。这使您有责任维护依赖关系本身,而不是在您试图测试的这个类中。(在这样做的过程中,尽量保持依赖关系的自由。)

一旦从类中完全删除了依赖项,您就可以随意地模拟和测试您喜欢的一切了。

票数 2
EN

Stack Overflow用户

发布于 2016-02-22 11:03:37

只需创建一个MS文件并将其放入包中,然后始终使用相同的文件进行测试,这样您甚至可以编写数据并确切地知道其返回的内容,而不是假设任何数据都返回正确!只是一个多方面的想法。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35551870

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档