这个DAL提供程序的例子中,除了集成测试之外,单元测试是否有任何价值?

3
public List<int> GetPortfolioList()
{
    using (var connection = new SqlConnection("<connectionString>"))
    using (var command = new SqlCommand("SELECT * FROM Portfolio", connection))
    {
        connection.Open();
        var portfolioTable = SqlHelper.GetDataTable(command);
        var portfolios = from DataRow row
                            in portfolioTable.Rows
                            select int.Parse(row["Portfolio"].ToString());

        return portfolios.ToList();
    }
}

这是一个用于检索投资组合列表的SQL DAL提供程序方法,如其名称(和代码)所示。由于集成测试的数据库表包含一组相当静态的数据,因此我们可以对多个期望进行断言,例如: - 不会为空 - 包含某些已知值 - 不包含重复项

经过同行评审后,有人坚持认为该代码没有得到适当的测试(在隔离状态下),因为它依赖于数据库访问。考虑到大部分价值在于确保该方法从保证状态的数据库返回数据,我无法看到模拟数据库调用以编写该方法的单元测试的价值。我是否漏掉了什么?

4个回答

4
我持相反的观点,因为我刚刚完成了编写一个虚假数据库(使用内存列表),以使linq to sql(或linq to anything)可进行单元测试。这是我用来选择适当的方式来伪造/模拟数据库的问题之一。(从阅读您的代码来看,“SELECT * FROM”嵌入式意味着您更倾向于SQL而不是linq,这将使您的代码更难分解为必须由SQL Server执行的内容和linq能够处理的内容。) 人们如何对使用Linq to SQL的代码进行单元测试 现在,即使数据库未连接到电源插座,我也可以运行单元测试,这些测试将根据我的linq查询的适用性成功或失败。
例如,如果row [“Portfolio”] .ToString()为空,代码将如何反应?当它不返回任何行或返回2行时,代码会如何反应?
即使您只进行集成测试,nunit也不是进行集成测试的坏方法,只要小心不要称其为单元测试,以免纯粹主义者感到不满。

3
该方法使用Linq从数据库中投影一些值到整数列表中 - 您可能希望测试它是否正确执行此操作。
我建议将代码分成两部分 - 数据检索和投影(Linq查询) - 您可以使用模拟数据测试Linq查询,而无需模拟数据库。
我还会说,对于数据访问代码,单元测试的价值很小。

这两种方式都不是单元测试他的代码。在其中一种方法中,您正在测试Linq实现,在另一种方法中,您正在集成测试db代码。 - heisenberg
@kekekela - 不,你将测试他对linq的使用是否符合预期,即他是否正确地使用它。 - Oded

2
作为一个测试纯粹主义者,我相信我无法“单元测试”数据访问层(DAL),因为我无法对其进行隔离测试。这意味着我的代码中的一部分,即与数据库交互的部分,没有经过单元测试。上面的代码看起来很好;只需确保它作为一个更大的契约的一部分存在,并且您可以在其他对象中测试它。
尽管如此,我会进行集成测试,通过构建一个数据库,填充数据,并确保我的DAL正常工作。

1

我同意你的观点,这里唯一有价值的是集成测试,如果不是过于苛求,实际上没有什么可以进行单元测试的。

当然,对于调用此方法的任何调用方的单元测试代码都应该将此方法模拟掉。

补充:在这种情况下,我认为马修·马丁提到的异常情况是唯一值得进行单元测试的东西。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接