【问题标题】:How to subclass a parent for mocking如何子类化父级以进行模拟
【发布时间】:2015-10-28 14:15:45
【问题描述】:

如何使用私有构造函数对父类进行子类化以便模拟它?

我已经重构了我的代码,这样当它调用第三方库时,调用是 包装,以便我可以模拟该类并创建一个假包装器。然后我理论上可以返回我想要的任何东西 使用依赖注入等测试我的生产代码。

对于一些库调用,返回一个对象实例,它本身就是一个特定的库 对象类型。在生产代码中,这随后会对该对象进行后续调用。

如下代码所示:

public class MyWrapper
{
  public LibraryObject MyWrappedCall()
  {
    LibraryObject x = ExternalLibrary.getLibObject();
    return x;
  }
}

public class MyProductionCode
{
  public void DoX()
  {
    LibraryObject lo = MyWrapper.getX();
    ProductionType pt = lo.doSomething();
  }
}

如何伪造方法 doSomething() ?我的第一个想法是而不是返回一个实例对象 从包装的调用中,返回一个相同类型的对象。因此可以增强 MyWrapper 代码 如下:

public class MyWrapper
{
  public LibraryObject MyWrappedCall()
  {
    //LibraryObject x = ExternalLibrary.getLibObject();
    MyMockLibraryObject mlo;
    return mlo;
  }

  public class MyMockLibraryObject extends LibraryObject
  {
    public ProductionType doSomething()
    {
      ProductionType pt;
      return pt;
    }
  }
}

这样做的问题是父类有一个私有构造函数,所以不能子类化。

有人对如何解决这个问题有任何建议吗?

【问题讨论】:

    标签: java unit-testing design-patterns mocking refactoring


    【解决方案1】:

    听起来很糟糕。您需要创建一个包装器接口(和实现)以从生产代码中隐藏 LibraryObject 类型,以便您可以模拟接口

    【讨论】:

    • 我不太担心 LibraryObject 类型是否在生产代码中,因为它已经在 Façade 中。我要做的就是返回一个我可以控制的对象,以便我可以选择在调用时返回给该对象的内容。
    【解决方案2】:

    最简单的解决方案是只模拟您需要模拟的任何第 3 方类型(但如果可能,更喜欢没有模拟的集成测试)。

    对于 Java,可以使用 PowerMock 或 JMockit 库执行此类模拟,而无需创建任何包装器。 (当然,如果所述包装器带来其他好处,那么您可能更愿意保留它们。)这些模拟库不通过创建子类来操作,因此它们不像那些那样受到限制。

    【讨论】:

      猜你喜欢
      • 2014-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多