Java 模拟静态类
我在一个类中有一个方法,它实例化一个静态类实例并对其调用操作Java 模拟静态类,java,unit-testing,mockito,powermock,Java,Unit Testing,Mockito,Powermock,我在一个类中有一个方法,它实例化一个静态类实例并对其调用操作 public class SomeClass { public void someMethod() { MyClass.MyStaticClass myStaticClassInstance = new MyClass.MyStaticClass( arg1, arg2, arg3 ); myStaticClassInstance.callSomeMethod(); }
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() {
}
}
}
如何模拟静态类实例,这样我就可以模拟
callsomethod()
,而无需经过静态类构造函数?您可以通过模拟静态内部类的实例化,使用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();
}
}
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");
}
}
}
public class MyOtherClass {
public void someMethod() {
MyClass.MyStaticClass myStaticClassInstance = new MyClass.MyStaticClass(
new Object(), new Object(), new Object()
);
myStaticClassInstance.callSomeMethod();
}
}
我的班级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();
}
}
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");
}
}
}
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
关于的更多细节。我编写了一个更简单的工具,用于模拟通常在 您的代码可以如下所示: ``` 公共类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();
}
}
```是的,很清楚,但不起作用。在执行
新建MyClass.MyStaticClass(arg1、arg2、arg3)时,执行将进入静态类的构造函数内部代码>这是我想要避免的。我没有在定义静态类的公共类中实例化静态类,这与您的代码不同。我将@PrepareForTest(MyClass.class)
更改为@PrepareForTest(SomeClass.class)
,它正在工作。谢谢你的代码示例,它对我帮助很大。首先,你不应该在SomeClass
中实例化MyStaticClass
。您应该使用依赖项反转将MyStaticClass
的实例注入SomeClass