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

时间:2008-08-27 12:29:09

标签: c# unit-testing tdd mocking

所以我正在研究一些对手动数据库操作很重要的遗留代码。我想在这里保持一些相似的质量,所以我尽可能地去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。

6 个答案:

答案 0 :(得分:1)

为了减少这种麻烦,您需要封装/重构DataReader与列表中保存的Object之间的映射。将这种逻辑封装起来的步骤很少。如果这是您想要的道路,我可以为您发布代码。我只是不确定在StackOverflow上发布代码是多么实用,但是我可以给它一个镜头来保持简洁和重点。否则,您将无法完成在读取器的索引访问器上重复每个期望的繁琐任务。封装过程也将摆脱字符串,并通过测试使这些字符串更可重用。

此外,我不确定您希望现有代码更易于测试多少。因为这是遗留代码,而不是考虑到测试而构建的。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

您可以将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

答案 3 :(得分:0)

KOKOS,

那里有些事情错了。首先,这样做意味着我必须首先构造Foos,然后将它们的值提供给模拟阅读器,它不会对减少我正在编写的代码量做任何事情。其次,如果值通过阅读器,则Foos将不是相同的 Foos(引用相等)。它们可能相等,但即便如此,假设Foo类过多,我此时也不敢触及。

答案 4 :(得分:0)

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

如果你想测试你的SQL调用返回了一些数据,我找到了here

的答案

答案 5 :(得分:0)

@Toran:我正在测试的是从数据库返回的数据到quote-unquote域模型的编程映射。因此我想模拟出数据库连接。对于其他类型的测试,我会进行全面的集成测试。

@Dale:我猜你在那里做得很好,我担心可能是这种情况。如果你有任何文章或类似的指针,有人做了肮脏的工作,并将其分解成更容易消化的步骤,我会很感激。代码样本也不会受到伤害。我确实知道如何解决这个问题,但在我真正敢于这样做之前,我需要完成其他事情,如果测试需要进行繁琐的嘲弄,那么这就是我要做的事情。 / p>