代码之家  ›  专栏  ›  技术社区  ›  Javid Jamae

自分流测试模式是否违反了单一责任原则?

  •  5
  • Javid Jamae  · 技术社区  · 14 年前

    参考文献: http://www.objectmentor.com/resources/articles/SelfShunPtrn.pdf

    4 回复  |  直到 14 年前
        1
  •  5
  •   Sadeq Dousti    4 年前

    对于单独的mock类,您可能认为它是自包含的,并且满足SRP,但是与mock类属性的语义耦合仍然存在。所以,真的,我们没有实现任何有意义的分离。

    public class ScannerTest extends TestCase implements Display
    {
      public ScannerTest (String name) {
        super (name);
      }
      public void testScan () {
        // pass self as a display
        Scanner scanner = new Scanner (this);
        // scan calls displayItem on its display
        scanner.scan ();
        assertEquals (new Item (“Cornflakes”), lastItem);
      }
      // impl. of Display.displayItem ()
      void displayItem (Item item) {
        lastItem = item;
      }
      private Item lastItem;
    }
    

    现在我们来模拟一下:

    public class DisplayMock implements Display
    {
      // impl. of Display.displayItem ()
      void displayItem (Item item) {
        lastItem = item;
      }
    
      public Item getItem() {
         return lastItem;
      }
      private Item lastItem;
    }
    
    public class ScannerTest extends TestCase
    {
      public ScannerTest (String name) {
        super (name);
      }
      public void testScan () {
        // pass self as a display
        DisplayMock dispMock = new DisplayMock();
        Scanner scanner = new Scanner (dispMock );
        // scan calls displayItem on its display
        scanner.scan ();
        assertEquals (new Item (“Cornflakes”), dispMock.GetItem());
      }
    }
    

    在实际应用中(IMHO)的耦合度较高 TestClass DisplayMock 是比违反SRP更大的罪恶 测试类 . 此外,通过使用mocking框架,这个问题完全解决了。

    编辑 我刚刚在罗伯特·C·马丁(Robert C.Martin)的优秀著作中遇到了一个关于自我分流模式的简短提及 Agile Principles, Patterns, and Practices in C# . 以下是书中的片段:

    我们可以通过使用数据库的抽象接口来实现这一点。这个抽象接口的一个实现使用真实的数据库。另一个实现是编写测试代码来模拟数据库的行为并检查数据库调用是否正确。结构如图29-5所示。这个 PayrollTest 模块测试 PayrollModule 通过调用它并实现 Database Payroll 工资测试 为了确保 工资单 行为正常。它还允许 嘲笑 .

    Figure 29-5. PayrollTest SELF-SHUNTs database

    因此,创造SRP的人(在同一本书中详细讨论过)对使用自分流模式没有任何疑虑。有鉴于此,我想说的是,在使用这种模式时,您对于OOP(面向对象的警察)是非常安全的。

        2
  •  3
  •   Carl Manaster    9 年前

    在我看来是的 违反规定,但很轻微。

    对你正在测试的东西的依赖。

    然而,这是一件坏事吗?为了几个简单的测试,可能不是。随着测试用例数量的增长,您可能需要重构并使用模拟类来分离一些关注点。(正如你贴的链接所说,自我分流是嘲笑的垫脚石)。但是如果测试用例的数量仍然是静态的和低的,那么问题是什么呢?

    我认为需要一点实用主义。是否违反SRP?是的,但我猜可能没有你测试的系统中的一些代码那么多。你需要做些什么吗?不,只要代码清晰且可维护就行,这对我来说永远是底线。SRP是一个准则,而不是一个规则。

        3
  •  1
  •   kyoryu    14 年前

    如果正在实现或分流的接口发生了变化,那么测试套件也相对有可能发生变化。所以我并不认为这违反了SRP。

        4
  •  1
  •   obelix    14 年前

    FWIW除非您使用的是C#(或python或类似工具)之类的强大工具,否则当您更改接口时,测试代码将发生更改。