【问题标题】:How should I write my unit tests for a child class? [closed]我应该如何为子类编写单元测试? [关闭]
【发布时间】:2021-05-07 04:28:50
【问题描述】:

假设我有一堂课

public class Foo extends Bar
{
   public Response post()
   {
      return authorize();
   }

   // override some additional methods from Bar class
}

和另一个班级

public class Bar
{
  public Response get()
  {
    return authorize();
  }

  public Response post()
  {
    return authorize();
  }

  public Response authorize()
  {
    // let's assume this method is "complicated" and has 200+ lines of code... lots of diff code paths etc
  }

}

所以我在考虑单元测试方面的几种不同方法

  1. 我直接调用authorize 并测试每一个可能的代码路径。然后我为FooBargetpost 方法编写了1 个快乐路径单元测试以确保完整性。

  2. 我直接调用两个类的getpost 方法,并决定只针对一种方法编写所有组合的测试。

  3. 我完全忽略了我的getpost 方法,并假设只要我完全测试我的authorize 方法我就很好。

我让这件事复杂化了吗?这里的最佳做法是什么。

【问题讨论】:

  • 我注意到这个问题已关闭,因为它被认为是“基于意见的”。我认为这是一个问题,询问是否有系统的继承测试技术。有,看答案。我建议重新提出问题(并就此投票)。

标签: java junit


【解决方案1】:

您可以考虑将authorize 方法提取到它自己的类中,例如Authorizer,并独立于FooBar 对其进行测试。您对Bar.getBar.postFoo.post 的测试可以模拟出Authorizer 并验证getpost 逻辑是否正确。

这基本上是您的第一个选项,但“测试每个可能的代码路径”部分封装在一个专用类中。

这种方法的一个很好的副作用是您还分离了您的关注点。 Authorizer 只关心授权,您的FooBar 类可以专注于它们的Foo-behavior 和Bar-behavior。从长远来看,这使您的代码更易于维护。

【讨论】:

  • 这是一个非常巧妙的方法。但是我的子类重写了authorize 方法中调用的一些方法,以提供特定于类的实现
  • 这让事情变得更难了 :) 可能仍然值得重构一些东西。如果您可以使用组合而不是继承,那么您可能能够解耦您的逻辑。例如,如果authorize 需要调用getWidget,那么您可以将其分解为WidgetProvider,并为Authorizer 提供一个。如果FooBar 也需要小部件,请将相同的WidgetProvider 连接到这些类。
【解决方案2】:

将其视为测试是否符合 Liskov 替换原则 (LSP) 的问题也可能会有所帮助。

超类Bar 提供合约。 Bar 的任何子类必须至少提供相同的合约——但它可能需要调用者少一点(更弱的前置条件,在更多情况下工作),并且可能会承诺更多一点(更强的后置条件,做更多的工作)它的调用者。

从您的测试策略 2 看来,您确实可以创建 Bar 的实例。这意味着你可以创建一个类BarTest,它严格测试Bar,给定一个类Bar的对象。

现在由于 LSP,同样的测试套件 BarTest 也必须传递 Bar 的任何子类,因此也传递 Foo。实现此目的的一种方法是创建一个简单地扩展BarTestFooTest 类,然后对Foo 类的对象运行相同的测试(例如,通过覆盖实际创建被测对象的工厂方法) .

然后,如果Foo 提供更多功能,您也可以在同一个FooTest 类中为这个新增功能添加单元测试。

就您的三个选项而言:

  1. 测试authorize 中的每一条路径,并为getpost 提供快乐路径:在BarTest 中编写测试用例,FooTest 将简单地继承它们。

  2. 继承将负责在两种上下文(BarFoo)中测试两种方法(getpost

  3. 如果事情很简单,忽略可能是一个很好的权衡。如果继承关系更复杂,系统的方法会有所帮助。

所有这些都来自 Binder 的 Polymorphic Server Test 模式和 McGregor 的 PACT -- 组件测试的并行架构。有关测试接口实现的问题,另请参阅 my earlier answer

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    • 2019-02-15
    • 2013-08-07
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多