如何测试实用程序项目的最终方法和静态方法?
我正在尝试为aproject实现单元测试,它使用一个遗留的“实用程序”项目,该项目充满了静态方法,许多类都是最终的,或者它们的方法都是最终的。我根本无法更新旧项目。
JMock和EasyMock都扼杀了最终的方法,我没有看到测试静态调用的好方法。有什么技术可以测试这些?
我正在尝试为aproject实现单元测试,它使用一个遗留的“实用程序”项目,该项目充满了静态方法,许多类都是最终的,或者它们的方法都是最终的。我根本无法更新旧项目。
JMock和EasyMock都扼杀了最终的方法,我没有看到测试静态调用的好方法。有什么技术可以测试这些?
如果能够重构代码,则可以将对 final/static 方法的调用包装在简单的实例方法中,例如:
protected Foo doBar(String name) {
return Utility.doBar(name);
}
这允许您在单元测试中重写包装器方法以返回 Foo 的模拟实例。
或者,您可以使用Powermock,它扩展了Easymock(和Mockito)以允许模拟最终和静态方法:
PowerMock是一个框架,它扩展了其他模拟库,如EasyMock,具有更强大的功能。PowerMock 使用自定义类装入器和字节码操作来模拟静态方法、构造函数、最终类和方法、私有方法、删除静态初始值设定项等。
下面是一个模拟静态最终方法的示例测试,该示例还显示了如何模拟其他一些类型:
@Test
public void testMockStaticFinal() throws Exception {
mockStatic(StaticService.class);
String expected = "Hello altered World";
expect(StaticService.sayFinal("hello")).andReturn("Hello altered World");
replay(StaticService.class);
String actual = StaticService.sayFinal("hello");
verify(StaticService.class);
assertEquals("Expected and actual did not match", expected, actual);
// Singleton still be mocked by now.
try {
StaticService.sayFinal("world");
fail("Should throw AssertionError!");
} catch (AssertionError e) {
assertEquals("\n Unexpected method call sayFinal(\"world\"):",
e.getMessage());
}
}
间接/依赖注入的水平如何?
由于旧版实用程序项目是依赖项,因此请创建一个接口以将其与代码分离。现在,此接口的实际/生产实现委托给旧版实用程序方法。
public LegacyActions : ILegacyActions
{
public void SomeMethod() { // delegates to final/static legacy utility method }
}
对于您的测试,您可以创建此接口的模拟,并避免与旧版实用程序进行交互。