代码之家  ›  专栏  ›  技术社区  ›  Rytmis

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

  •  5
  • Rytmis  · 技术社区  · 16 年前

    因此,我正在处理一些遗留代码,这些代码在手动数据库操作上很重。我试图在这里保持一些质量,所以我尽可能地采用TDD。

    我正在编写的代码需要填充,比如 List<Foo> 从DataReader返回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。嘲笑这一点,但如果结果足够令人信服,我可以改变它。只要替代品不是TypeMock,因为他们的EULA对我上次检查的口味来说有点太可怕了。

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

    6 回复  |  直到 16 年前
        1
  •  1
  •   Dale Ragan    16 年前

    为了使这不那么乏味,您需要封装/重构DataReader和列表中包含的对象之间的映射。封装该逻辑的步骤很少。如果你想走那条路,我可以帮你发代码。我只是不确定在StackOverflow上发布代码有多实用,但我可以尝试保持简洁明了。否则,您将陷入在索引访问器上为读者重复每个期望的乏味任务。封装过程还将去除字符串,并使这些字符串在测试中更具可重用性。

    此外,在这一点上,我不确定你有多想让现有的代码更具可测试性。因为这是没有考虑到测试的遗留代码。

        2
  •  1
  •   Dale Ragan    16 年前

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

        3
  •  0
  •   kokos    16 年前

    您可以将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
  •  0
  •   Rytmis    16 年前

    科科斯,

    有几件事不对。首先,这样做意味着我必须先构造Foos,然后将它们的值提供给模拟阅读器,而模拟阅读器对 减少 我正在编写的代码量。其次,如果值通过读取器,则Foos不会是 相同的 Foos(引用等式)。他们可能是 相等的 ,但即便如此,这也是对Foo类的太多假设,我现在不敢碰。

        5
  •  0
  •   Community CDub    8 年前

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

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

        6
  •  0
  •   Rytmis    16 年前

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

    @戴尔:我想你把它钉得很好,我担心情况可能就是这样。如果你有任何文章或类似文章,其中有人做了脏活累活,并将其分解为更容易理解的步骤,我将不胜感激。代码示例也不会有什么坏处。我确实知道如何解决这个问题,但在我真正敢于这样做之前,我需要完成其他事情,如果测试需要乏味的嘲笑,那么这就是我要做的。