java 模拟静态类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41804287/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mocking static class
提问by jerome
I have a method in a class that instantiate a static class instance and call operation on it.
我在一个类中有一个方法,它实例化一个静态类实例并对其调用操作。
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() {
}
}
}
How to mock static class instanciation, so that I could mock callSomeMethod()
without going through the static class constructor ?
如何模拟静态类实例化,以便我可以在callSomeMethod()
不通过静态类构造函数的情况下进行模拟?
采纳答案by Nicolas Filotto
You can do it with PowerMock
by mocking instantiation of your static inner class. This can be done by preparing the class that will actually instantiate your static inner class so here it will be the class in which you have the method someMethod()
defined.
您可以PowerMock
通过模拟静态内部类的实例化来实现。这可以通过准备实际实例化静态内部类的类来完成,因此这里将是您someMethod()
定义方法的类。
Assuming that someMethod()
is defined into the class MyOtherClass
and returns nothing, your test class would be something like this:
假设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();
}
}
Assuming that my class MyClass
looks like this:
假设我的班级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");
}
}
}
And my class MyOtherClass
looks like this:
我的班级MyOtherClass
看起来像这样:
public class MyOtherClass {
public void someMethod() {
MyClass.MyStaticClass myStaticClassInstance = new MyClass.MyStaticClass(
new Object(), new Object(), new Object()
);
myStaticClassInstance.callSomeMethod();
}
}
If I launch my test, I get as expected:
如果我启动我的测试,我会得到预期的结果:
My new Answer
Instead of what I should get by default:
而不是我默认应该得到的:
Called constructor
callSomeMethod
More details about how to constructions of new objects.
有关如何构造新对象的更多详细信息。
回答by iirekm
I wrote a simpler tool for mocking things that are normally 'non-mockable' at https://github.com/iirekm/misc/tree/master/ajmock
我在https://github.com/iirekm/misc/tree/master/ajmock写了一个更简单的工具来模拟通常“不可模拟”的东西
Your code can look like:
您的代码可能如下所示:
``` public class MyClassTest {
``` 公共类 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();
}
}
}
```
``