2

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

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

LegacyClass legacyClass = mock(LegacyClass.class);

我最终得到一个ExceptionInInitializationError表明它找不到某个属性键的结果。

在 LegacyClass.java 中,有:

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

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

4

2 回答 2

2

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

您需要执行以下操作才能开始使用 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 初始化并为静态级别模拟注册正确的类。

于 2013-08-01T19:03:48.513 回答
1

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

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

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

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

于 2013-08-01T16:25:31.467 回答