单元测试是否会在集成测试之外为DAL提供程序的这个示例添加任何值?

时间:2011-01-07 18:02:29

标签: c# unit-testing tdd integration-testing

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 个答案:

答案 0 :(得分:4)

我会采取相反的观点,因为我刚刚完成了一个假db(在内存列表中使用)来使linq到sql(或linq to anything)单元可测试。

这是我用来挑选伪造/模拟数据库的合适方法的一个问题。 (从阅读您的代码来看,嵌入式“SELECT * FROM”意味着您更倾向于SQL而不是linq,这将使您更难将代码分解为具有由SQL Server执行的内容以及linq能够处理的东西。

How are people unit testing code that uses Linq to SQL

我现在可以运行成功或失败的单元测试,具体取决于我的linq查询的适用性,即使数据库已从墙上拔下

例如,如果row [“Portfolio”]。ToString()为null,代码如何反应,当代码没有返回任何行时,代码如何反应,或返回2?

即使你只是进行集成测试,nunit也不是集成测试的坏方法,只要注意不要将它们称为单元测试,以免纯粹主义者对此感到不安。

答案 1 :(得分:3)

该方法使用Linq将数据库中的某些值投影到整数列表中 - 您可能希望测试它是否正确执行此操作。

我会将代码分成两部分 - 数据检索和投影(Linq查询) - 然后您可以使用mock data 测试linq查询,而无需模拟数据库。

我还说单元测试数据访问代码没什么价值。

答案 2 :(得分:2)

作为一名测试纯粹主义者,我相信我无法对DAL进行“单元测试”,因为我无法孤立地进行测试。这意味着我的代码的一部分,即与数据库交互的代码,没有单元测试。上面的代码看起来很好;只需确保它作为较大合同的一部分存在,您可以在其他对象中进行测试。

我确实通过构建数据库,播种并确保我的DAL正常工作来执行集成测试。

答案 3 :(得分:1)

我同意你的观点,这里唯一的价值就是集成测试,没有迂腐,没有什么可以进行单元测试。

此方法的任何调用者的单元测试代码当然应该模仿这种方法。

e:MathewMartin上面提到的例外案例是我在这种情况下唯一值得单元测试的事情。