我正在尝试使用Powermock模拟对数据库的调用。这是我们的代码的示例:
public class WrapperClass {
public static SearchUtil searchUtil = new SearchUtil();
}
public class SearchUtil {
public Record searchForThing(String thing) {
// Makes a call to a database and returns a record
}
}
public class TestableClass {
public void runMethod() {
// When this is called, it returns null, however based on the debugger, WrapperClass.searchUtil is a mocked object
WrapperClass.searchUtil.searchForThing("thing");
}
}
@PrepareForTest(WrapperClass.class)
@PowerMockIgnore({"javax.management.*", "javax.xml.parsers.*", "com.sun.org.apache.xerces.internal.jaxp.*", "ch.qos.logback.*", "org.slf4j.*", "org.apache.xerces.*", "javax.xml.*", "org.xml.sax.*", "org.w3c.dom.*"})
@RunWith(PowerMockRunner.class)
public class MyTest {
@Test
public void runMyTest() {
SearchUtil searchUtil = PowerMockito.mock(SearchUtil.class);
PowerMockito.mockStatic(WrapperClass.class);
Whitebox.setInternalState(WrapperClass.class, "searchUtil", searchUtil);
PowerMockito.doReturn(new SearchRecord()).when(WrapperClass.searchUtil).searchForThing("thing");
// When the below call is made, a new SearchRecord is returned and is not null
WrapperClass.searchUtil.searchForThing("thing");
// Calling the method that calls the searchForThing method, when searchForThing is called inside runMethod, it returns null
new TestableClass().runMethod();
}
}
我知道静态变量等绝对不是最佳实践,但是现在让我们假装无法更改它。在测试中调用被模拟的调用时,它将按预期返回新的SearchRecord
。在runMethod
中调用该函数时,它返回null,但是searchUtil
对象是根据我的调试器的模拟对象。当调用存根方法的嵌套嵌套时,为什么会发生这种情况?
答案 0 :(得分:0)
查看以下内容,其行为应与预期一样。
@PowerMockIgnore({"javax.management.*", "javax.xml.parsers.*", "com.sun.org.apache.xerces.internal.jaxp.*", "ch.qos.logback.*", "org.slf4j.*", "org.apache.xerces.*", "javax.xml.*", "org.xml.sax.*", "org.w3c.dom.*"})
@RunWith(PowerMockRunner.class)
@PrepareForTest(WrapperClass.class, TestableClass.class)
public class MyTest {
@Test
public void runMyTest() {
//Arrange
Record expected = new SearchRecord();
String arg = "thing";
SearchUtil searchUtil = PowerMockito.mock(SearchUtil.class);
when(searchUtil.searchForThing(arg)).thenReturn(expected);
// mock all the static members in WrapperClass class
PowerMockito.mockStatic(WrapperClass.class);
// use Mockito to set up your expectation
when(WrapperClass.searchUtil).thenReturn(searchUtil);
TestableClass subject = new TestableClass();
//Act
subject.runMethod();
//Assert
//...
}
}
请注意测试流程。
我还建议确保测试中使用的参数与执行的方法传递的参数匹配,因为如果不匹配,则由于参数/参数不匹配,它也会返回 null
否则,您将需要松开参数匹配器
//...
when(searchUtil.searchForThing(any(String.class))).thenReturn(expected);
//...
您也可以查看the powermock-mockito docs here,以更好地了解如何使用该框架。