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

使用PowerMock,或者让测试在多大程度上影响设计?[闭门]

  •  15
  • tddmonkey  · 技术社区  · 17 年前

    我多年来一直是EasyMock的粉丝,多亏了这一点,我遇到了对PowerMock的引用,以及它模拟构造函数和静态方法的能力,这两种能力在将测试改装到遗留代码库时都会导致问题。

    1. 回到初始化合作者而不是注入他们

    除此之外,关于我的代码在测试中被字节码操纵的问题,我也不太清楚。我真的不能给出具体的原因,只是它让我感到有点不安,因为它只是为了测试,而不是为了生产。

    在我目前的工作中,我们真的在推动单元测试,以此作为人们改进编码实践的一种方式,感觉将PowerMock引入等式可能会让人们跳过这一步,因此我不愿意开始使用它。话虽如此,我真的可以看出利用它可以减少需要进行的重构量 测试一个类。

    我想我的问题是,人们在使用PowerMock(或任何其他类似的库)实现这些功能方面有什么经验,您会利用它们吗?您希望您的测试在多大程度上影响您的设计?

    6 回复  |  直到 17 年前
        1
  •  15
  •   David Schumann Axnyff    5 年前

    我不得不强烈反对这个问题。

    没有理由使用限制设计选择的模拟工具。EasyMock、EasyMock类扩展、jMock、Mockito等排除的不仅仅是静态方法。这些工具还阻止您声明类和方法 final 有关类和方法,请参阅“effectivejava”一书,或观看以下内容 presentation (来自作者。)

    “初始化合作者而不是注入他们”通常是最重要的 设计,以我的经验。如果通过创建从该类实例化的帮助器类来分解解决某些复杂问题的类,则可以利用将特定数据安全地传递给这些子对象的能力,同时对客户端代码(提供高级操作中使用的完整数据)隐藏它们。在公共API中公开此类助手类违反了信息隐藏、破坏封装和增加客户机代码复杂性的原则。

    DI的滥用导致了无状态对象的出现,这些对象实际上应该是有状态的,因为它们将 几乎总是 对特定于业务操作的数据进行操作。 这不仅适用于非公共助手类,也适用于从UI/presentation对象调用的公共“业务服务”类。此类服务类通常是内部代码(针对单个业务应用程序),本质上是不可重用的,并且只有少数客户机(通常只有一个),因为此类代码本质上是可重用的 .

    JMockit 工具箱。我考虑的不是遗留代码,而是设计的简单性和经济性。到目前为止,我取得的成绩使我确信 真的是一个由两个变量组成的函数: 维修性 全部的

        2
  •  13
  •   Jan Kronquist    17 年前

    我完全同意可测试性不是最终目标,这是我在开发PowerMock时意识到的事情之一。我也同意编写单元测试是获得良好设计的一种方法。使用PowerMock可能是一个例外,而不是一个规则,至少是一些特性,比如对构造函数的期望和静态模拟。

    anti-corruption-layer 这将抽象第三方代码并使其可测试。然而,有时我认为仅仅使用标准API代码就更干净了。javameapi就是一个很好的例子。这里充满了阻止单元测试的静态方法调用。

    我们的问题是指定一组最佳实践规则,以供新手在何时使用PowerMock或不使用PowerMock时遵循。创建好的设计真的很难,因为PowerMock为您提供了更多的选择,也许对于初学者来说就更难了?我认为经验更丰富的开发人员更喜欢有更多的选择。

    (创办人) PowerMock

        3
  •  5
  •   SamBeran    17 年前

    我认为你是对的——如果你需要PowerMock,你可能有很臭的代码。把那些静力学处理掉。

    然而,我认为你对字节码插装的看法是错误的。我一直用计算机模拟具体的课程 mockito -它使我不必为它编写接口 每一个仅有一个的班 . 那要干净得多。

    只有您可以防止代码气味。

        4
  •  4
  •   RoyOsherove    17 年前

    在.NET竞技场上,关于Typemock隔离器,我们遇到了许多相同的问题。 This blog post

    我认为,当人们开始意识到可测试性不是最终目标,设计是通过其他方式学习的,那么我们将不再让恐惧支配我们使用哪些工具,或者在相关的时候不使用更先进的技术。

    此外,能够根据应用程序需求选择设计方式也是有意义的。不要让工具告诉你如何设计——它会让你别无选择。

    (我在Typemock工作,但曾经反对过)

        5
  •  3
  •   Jeffrey Fredrick    17 年前

    那么难 在里面

    与其走捷径学坏习惯,不如走慢一点,有一个有利于学习的环境。

    (我只是 read this

        6
  •  0
  •   Nitin Labhishetty    9 年前

    Powermock提供的过度反射的抽象层看起来很吸引人,但它使测试变得脆弱。更具体地说:

    1. Powermock的stubing特性 new ,静态方法调用等,使您了解函数的实现细节。测试应该理想地测试功能,例如。

      functionOldImplementation(){
          List l = new ArrayList();
      }
      // old implementation changed to new
      functionNewImplementation(){
          List l = new LinkedList();
      }
      

    嘲弄 new ArrayList() 调用将破坏上述重构的测试。运行回归最需要测试,如果这样做,测试就会失败。

    最近遇到了这个 article ,它解决了问题中提出的大部分问题,我想与大家分享一下。

    1. 使PowerMock+Javaassist与兼容需要1.5年的时间 Java7自推出以来。以下是PowerMock更改日志中的注释:

      Change log 1.5 (2012-12-04)  
      ---------------------------     
      Upgraded to Javassist 3.17.1-GA, this means that PowerMock works in Java 7!
      
    2. PowerMock网站说:

    开发商可能弊大于利”。