我应该如何测试从 DataReader 填充列表的方法?

Posted

技术标签:

【中文标题】我应该如何测试从 DataReader 填充列表的方法?【英文标题】:How should I test a method that populates a list from a DataReader? 【发布时间】:2010-09-06 23:55:06 【问题描述】:

所以我正在处理一些对手动数据库操作很繁重的遗留代码。我试图在这里保持一些表面上的质量,所以我会尽可能地使用 TDD。

我正在处理的代码需要填充,比如说来自 DataReader 的 List<Foo>,它返回正常运行的 Foo 所需的所有字段。但是,如果我想验证代码实际上是否为每个数据库行返回一个列表项,我正在编写如下所示的测试代码:

Expect.Call(reader.Read()).Return(true);
Expect.Call(reader["foo_id"]).Return((long) 1);
// ....
Expect.Call(reader.Read()).Return(true);
Expect.Call(reader["foo_id"]).Return((long) 2);
// ....
Expect.Call(reader.Read()).Return(false);

这也相当乏味且很容易损坏。

我应该如何处理这个问题,这样结果才不会是一大堆脆弱的测试?

顺便说一句,我目前正在为此使用 Rhino.Mocks,但如果结果足够令人信服,我可以更改它。只要替代品不是 TypeMock,因为他们的 EULA 对我上次检查的口味来说有点太吓人了。

编辑:我目前也仅限于 C# 2。

【问题讨论】:

【参考方案1】:

为了减少繁琐,您需要封装/重构 DataReader 和您在列表中保存的对象之间的映射。封装该逻辑的步骤很少。如果那是您想走的路,我可以为您发布代码。我只是不确定将代码发布到 *** 上会有多实用,但我可以试一试以使其简洁明了。否则,您将被困在为读者重复索引访问器的每个期望的繁琐任务中。封装过程也会去掉字符串,让这些字符串在您的测试中更易于重用。

此外,我目前不确定您希望使现有代码更具可测试性的程度。因为这是在构建时未考虑测试的遗留代码。

【讨论】:

【参考方案2】:

我想发布一些代码,然后我想起了 JP Boodhoo 的 Nothin But .NET 课程。他有一个sample project,他正在分享它是在他的一个课程中创​​建的。该项目托管在Google Code 上,它是一个很好的资源。我相信它有一些不错的技巧供您使用,并为您提供有关如何重构映射的想法。整个项目都是用 TDD 构建的。

【讨论】:

【参考方案3】:

您可以将 Foo 实例放在一个列表中,并将对象与您阅读的内容进行比较:

var arrFoos = new Foos[]...; // what you expect
var expectedFoos = new List<Foo>(arrFoos); // make a list from the hardcoded array of expected Foos
var readerResult = ReadEntireList(reader); // read everything from reader and put in List<Foo>
Expect.ContainSameFoos(expectedFoos, readerResult); // compare the two lists

【讨论】:

【参考方案4】:

科科斯,

那里有几件事不对劲。首先,这样做意味着我必须先构建 Foos,然后将它们的值提供给模拟阅读器,这对 减少我正在编写的代码量没有任何作用。其次,如果值通过读取器,Foos 将不是 same Foos(引用相等)。它们可能相等,但即使这样也假设了太多我现在不敢触及的 Foo 类。

【讨论】:

【参考方案5】:

澄清一下,您希望能够测试您对 SQL Server 的调用是否返回了一些数据,或者如果您有一些数据可以将其映射回模型中?

如果您想测试您对 SQL 的调用返回了一些数据,请查看我的答案 here

【讨论】:

【参考方案6】:

@Toran:我正在测试的是从数据库返回的数据到引用-取消引用域模型的编程映射。因此我想模拟出数据库连接。对于另一种测试,我会进行全面的集成测试。

@Dale:我猜你在这方面做得很好,我担心可能是这样。如果您有任何文章或类似内容的指针,其中有人完成了肮脏的工作并将其分解为更容易消化的步骤,我将不胜感激。代码示例也不会受到伤害。我确实知道如何解决这个问题,但在我真正敢于这样做之前,我需要完成其他事情,如果测试需要进行乏味的模拟,那么这就是我要做的。

【讨论】:

以上是关于我应该如何测试从 DataReader 填充列表的方法?的主要内容,如果未能解决你的问题,请参考以下文章

遇到“DataReader 已打开”的问题

使用 datareader 填充 mvc 模型时解决对象引用错误?

如何使用 datareader 从数据表中读取

我应该如何跟踪打开的 DataReader?

如何从mysql数据库填充下拉列表并且不应该重复值

在 C# 中将 SQL Datareader 转换为数据集