【问题标题】:Mocking a dependency on a property file模拟对属性文件的依赖
【发布时间】:2013-08-01 15:29:28
【问题描述】:

我正在尝试编写一个涉及使用遗留代码的单元测试。问题是,据我所知,遗留代码使用属性文件中的键/值对来初始化其最终的静态私有成员之一,而我对该属性文件的位置一无所知(整个应用程序非常庞大)。

所以,在我的测试中,我想做这样的事情(使用 Mockito):

LegacyClass legacyClass = mock(LegacyClass.class);

我最终得到一个ExceptionInInitializationError,这表明它找不到某个属性键。

在 LegacyClass.java 中,有:

private static final int LEGACY_PROPERTY = 
    Integer.parseInt(LegacyPropertyManager.getProp("legacy.property.key"));

有没有办法编写一个使用这个遗留类的测试,即使它正在寻找的属性键不存在?可以以某种方式嘲笑它吗?

【问题讨论】:

  • 为单元测试添加您自己的属性文件,例如here
  • @RobGarwood 但问题是它是使用该属性的遗留类 - 如何让 LegacyClass 在实例化时使用我自己的属性文件,而不是 LegacyPropertyManager 查找的那个?
  • @JeffBowman 确实很聪明;虽然我不太确定如何使用 mockStatic 来模拟 getProp 以便它使用我的属性文件。在我的单元测试中,我尝试模拟LegacyPropertyManager,然后像您链接到的示例中那样设置when(...).thenReturn(...),但看起来LegacyClass 仍然使用原来的。我需要做一个额外的步骤吗?
  • @dashik 提升一个答案,给它自己的线程。

标签: java unit-testing junit mockito


【解决方案1】:

如果没有像 PowerMock 这样的聪明库,您可能不会走得太远。请注意,您的 LegacyClass.java 在静态 final 字段中初始化此属性,这意味着初始化程序将在加载后立即运行。 PowerMock 使用更深层次的魔法(阅读:字节码操作)让您可以mock the static getProp method 您在上面引用。

您需要执行以下操作才能开始使用 PowerMockito:

@RunWith(PowerMockRunner.class)
@PrepareForTest(LegacyPropertyManager.class)
public class YourClass {

  @Before public void stubLegacyPropertyManager() {
    Mockito.when(LegacyPropertyManager.getProp("legacy.property.key"))
        .thenReturn("42");
  }

  @Test public void yourTest() {
    // ...
  }
}

注意类级别的注释,它们分别允许 PowerMock 初始化和注册正确的类以进行静态级别的模拟。

【讨论】:

  • 在这种情况下,我没有得到getProp。得到错误。在 Eclipse 建议中,它要求执行 getProperties. 但测试用例失败了。
  • @David 听起来您的问题可能略有不同。 cmets 不是解决问题的好地方,因为评论框很小且格式受限;请考虑提出一个新的顶级问题。要显示研究/尝试,您可以链接到此答案并描述它的哪些部分不适合您。
  • 我在这里添加一个问题。请看一看。 stackoverflow.com/questions/51297854/…
【解决方案2】:

模拟属性文件的示例,完全忽略它的位置如下。您可以直接在模拟的属性对象中创建自己的一组键/值对。

Properties mockProperties = mock(Properties.class);
when((mockProperties.getProperty("keyName"))).thenReturn("value");

让您的旧类使用此对象可能涉及对旧类的代码更改,例如将私有属性对象更改为受保护或创建一个 set 方法。

当无法增强遗留代码时,我知道您可以冒险进入部分模拟/间谍(Mockito 1.8)领域,如以下帖子中所述..Mockito bypass static method for testing 及其到Effective Mockito 的链接。我没有使用它们,所以我无法提供更多帮助。祝你好运。

【讨论】:

  • 知道有用,但不幸的是我不允许触摸遗留类代码。
  • 如果不允许你接触类代码,那么如果你的测试发现了该代码中的错误,你会怎么做?
  • 啊,为了澄清,我没有测试遗留代码。它自 90 年代后期以来一直在使用(尽管按照今天的标准写得不好),所以我们知道它是功能性的。我只需要编写一个使用该遗留代码的类(和单元测试),但它糟糕的设计让我很难嘲笑它。我向我的老板提出了关于获得重构许可的请求,他说他会尝试对此做些什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-25
相关资源
最近更新 更多