使用静态方法处理最终 Class
Deal with Final Class With Static Method
我有一个方法,我想测试一下。在那里,我调用了最终 Hybris-class (Config.getParameter("aString")
) 的静态方法。我想嘲笑它,但我发现,你不能用 Mockito 做到这一点。那么解决这个问题的好方法是什么?问题是,我正在考虑重构。但是我无法更改 Config-class,因为它来自 Hybris。
如何更改我的 class 我想测试,以便我可以影响 Config.getParameter("aString")
调用?
谢谢!
一个解决方案是创建一个接口,其方法(或多个方法)与您对 Config
class 的期望相匹配。然后您可以执行以下操作:
- 创建一个在生产中使用
Config
的实现;
- 为您的测试创建模拟。
使用 Java 8 的简化示例:
// The interface
public interface MyInterface
{
String getParameter(String paramName);
}
// Class using the interface
public final class MyClass
{
private final MyInterface intf;
// For testing...
public MyClass(final MyInterface intf)
{
this.intf = Objects.requireNonNull(intf);
}
// In production...
public MyClass()
{
this(Config::getParameter);
}
// etc
}
// Test class
@Test
public void whatever()
{
final MyInterface intf = mock(MyInterface.class);
// set up the mock, then...
final MyClass myClass = new MyClass(intf);
// test myClass
}
除了 Mockito 之外,您还可以使用工具调用 PowerMock,这对您的用例很有帮助。
有两种方法:
1.Refactor你的代码和引入ConfigWrapper(例如)接口:
public interface ConfigWrapper {
public String getParameter(String parameter);
public class ConfigWrapperImpl implements ConfigWrapper{
public String getParameter(String parameter){
return Config.getParameter(parameter);
}
}
然后你应该重构你的代码并通过注入 ConfigWrapper 替换 Config.* 用法。当您编写测试时,您可以使用 mockito 轻松模拟 ConfigWrapper(因为您使用的是非静态方法)
第二种方式是使用PowerMock代替mockito:
PowerMock.mockStatic(ClassThatContainsStaticMethod.class)
更多信息你可以看到:https://github.com/jayway/powermock/wiki/MockStatic
我有一个方法,我想测试一下。在那里,我调用了最终 Hybris-class (Config.getParameter("aString")
) 的静态方法。我想嘲笑它,但我发现,你不能用 Mockito 做到这一点。那么解决这个问题的好方法是什么?问题是,我正在考虑重构。但是我无法更改 Config-class,因为它来自 Hybris。
如何更改我的 class 我想测试,以便我可以影响 Config.getParameter("aString")
调用?
谢谢!
一个解决方案是创建一个接口,其方法(或多个方法)与您对 Config
class 的期望相匹配。然后您可以执行以下操作:
- 创建一个在生产中使用
Config
的实现; - 为您的测试创建模拟。
使用 Java 8 的简化示例:
// The interface
public interface MyInterface
{
String getParameter(String paramName);
}
// Class using the interface
public final class MyClass
{
private final MyInterface intf;
// For testing...
public MyClass(final MyInterface intf)
{
this.intf = Objects.requireNonNull(intf);
}
// In production...
public MyClass()
{
this(Config::getParameter);
}
// etc
}
// Test class
@Test
public void whatever()
{
final MyInterface intf = mock(MyInterface.class);
// set up the mock, then...
final MyClass myClass = new MyClass(intf);
// test myClass
}
除了 Mockito 之外,您还可以使用工具调用 PowerMock,这对您的用例很有帮助。
有两种方法:
1.Refactor你的代码和引入ConfigWrapper(例如)接口:
public interface ConfigWrapper {
public String getParameter(String parameter);
public class ConfigWrapperImpl implements ConfigWrapper{
public String getParameter(String parameter){
return Config.getParameter(parameter);
}
}
然后你应该重构你的代码并通过注入 ConfigWrapper 替换 Config.* 用法。当您编写测试时,您可以使用 mockito 轻松模拟 ConfigWrapper(因为您使用的是非静态方法)
第二种方式是使用PowerMock代替mockito:
PowerMock.mockStatic(ClassThatContainsStaticMethod.class)
更多信息你可以看到:https://github.com/jayway/powermock/wiki/MockStatic