我在类中有一个实例化静态类实例并对其调用操作的方法。
public class SomeClass {
public void someMethod() {
MyClass.MyStaticClass myStaticClassInstance =
new MyClass.MyStaticClass( arg1, arg2, arg3 );
myStaticClassInstance.callSomeMethod();
}
}
public class MyClass {
public static class MyStaticClass {
public MyStaticClass( Object arg1, Object arg2, Object arg3 ) {
}
public void callSomeMethod() {
}
}
}
如何模拟静态类实例化,以便我可以在不通过静态类构造函数的情况下模拟callSomeMethod()
?
模拟静态内部类的实例化来PowerMock
做到这一点。这可以通过准备实际实例化静态内部类的类来完成,因此这里它将是您在其中定义了方法someMethod()
的类。
假设someMethod()
被定义为类MyOtherClass
并且不返回任何内容,则测试类将如下所示:
@RunWith(PowerMockRunner.class) // The runner of PowerMock
@PrepareForTest(MyOtherClass.class) // the class to prepare
public class MyClassTest {
@Test
public void test() throws Exception {
// The mock of your static inner class to return
MyClass.MyStaticClass mock = Mockito.mock(MyClass.MyStaticClass.class);
// Mock the call of callSomeMethod()
PowerMockito.doAnswer(
new Answer<Void>() {
@Override
public Void answer(final InvocationOnMock invocation) throws Throwable {
// Do something here as new implementation of callSomeMethod
System.out.println("My new Answer");
return null;
}
}
).when(mock).callSomeMethod();
// Return your mock in case we instantiate MyClass.MyStaticClass in
// the prepared class with any arguments
PowerMockito.whenNew(MyClass.MyStaticClass.class)
.withArguments(Matchers.any(), Matchers.any(), Matchers.any())
.thenReturn(mock);
// The code that will call someMethod
MyOtherClass mc = new MyOtherClass();
mc.someMethod();
}
}
假设我的类MyClass
如下所示:
public class MyClass {
public static class MyStaticClass {
public MyStaticClass(Object arg1, Object arg2, Object arg3) {
System.out.println("Called constructor");
}
public void callSomeMethod() {
System.out.println("callSomeMethod");
}
}
}
我的类MyOtherClass
看起来像这样:
public class MyOtherClass {
public void someMethod() {
MyClass.MyStaticClass myStaticClassInstance = new MyClass.MyStaticClass(
new Object(), new Object(), new Object()
);
myStaticClassInstance.callSomeMethod();
}
}
如果我启动测试,我会得到预期:
My new Answer
而不是我默认应该得到的:
Called constructor
callSomeMethod
有关如何构造新对象的更多详细信息。
我写了一个更简单的工具,用于模拟通常"不可模拟"的东西 https://github.com/iirekm/misc/tree/master/ajmock
您的代码可能如下所示:
''' 公共类 MyClassTest {
@Test
public void test() throws Exception {
MyClass.MyStaticClass mock = Mockito.mock(MyClass.MyStaticClass.class);
when(() -> mock.callSomeMethod()).thenAnswer(() -> ...);
when(() -> new MyClass.MyStaticClass(any(), any(), any())).thenReturn(mock);
// The code that will call someMethod
MyOtherClass mc = new MyOtherClass();
mc.someMethod();
}
}
'''