[英]Mocking chained methods calls using PowerMock
I have a class which I would like to test with a public static method that contains some chained method calls. 我有一个要通过公共静态方法测试的类,该方法包含一些链接的方法调用。 Assuming that an exception occurs during the chained method calls, how do I handle this effectively and make it return some specific value?
假设在链接方法调用期间发生异常,如何有效地处理此异常并使它返回某些特定值?
Following is the code sample of the test class. 以下是测试类的代码示例。
@RunWith(PowerMockRunner.class)
@PrepareForTest({CodeWithPrivateMethod.class,CodeWithAnotherPrivateMethod.class,CodeWithYetAnotherPrivateMethod.class})
public class CodeWithPrivateMethodTest {
@Test
public void when_gambling_is_true_then_always_explode() throws Exception {
CodeWithYetAnotherPrivateMethod codeWithYetAnotherPrivateMethod = PowerMockito.spy(new CodeWithYetAnotherPrivateMethod());
PowerMockito.whenNew(CodeWithYetAnotherPrivateMethod.class).withAnyArguments().thenReturn(codeWithYetAnotherPrivateMethod);
CodeWithAnotherPrivateMethod codeWithAnotherPrivateMethod = PowerMockito.spy(new CodeWithAnotherPrivateMethod());
PowerMockito.whenNew(CodeWithAnotherPrivateMethod.class).withAnyArguments().thenReturn(codeWithAnotherPrivateMethod);
PowerMockito.doReturn(true).when(codeWithYetAnotherPrivateMethod, "getGambling");
//PowerMockito.doReturn(codeWithYetAnotherPrivateMethod).when(codeWithAnotherPrivateMethod, "getGambleValue");
PowerMockito.spy(CodeWithPrivateMethod.class);
CodeWithPrivateMethod.startGamble();
}
}
Following is the code sample for the class under test 以下是被测类的代码示例
public class CodeWithPrivateMethod {
public static void startGamble() {
Boolean gamble = CodeWithAnotherPrivateMethod.getGambleValue()
.getGambling();
if (gamble) {
System.out.println("kaboom");
}else{
System.out.println("boom boom");
}
}
}
Following is the code sample for the class that gets called from the class under test 以下是从被测类调用的类的代码示例
public class CodeWithAnotherPrivateMethod {
static CodeWithYetAnotherPrivateMethod codeWithYetAnotherPrivateMethod = new CodeWithYetAnotherPrivateMethod();
public static CodeWithYetAnotherPrivateMethod getGambleValue() {
return codeWithYetAnotherPrivateMethod; //works fine
return null; // fails
}
}
Following is the code sample for the other class that gets called from the class under test 以下是从被测类调用的另一个类的代码示例
public class CodeWithYetAnotherPrivateMethod {
public Boolean getGambling() {
return false;
}
}
So Assuming I return a null value from getGambleValue() method of CodeWithAnotherPrivateMethod class, how do I handle this null value effectively in my testclass? 因此,假设我从CodeWithAnotherPrivateMethod类的getGambleValue()方法返回了空值,如何在我的测试类中有效地处理该空值?
This is how to specify expected exceptions using Mockito: 这是使用Mockito指定预期异常的方法:
@Test(expected = NullPointerException.class)
public void when_gambling_is_true_then_always_explode() throws Exception {
...
Before I found out about this I would do: 在我发现这一点之前,我会做:
@Test
public void when_gambling_is_true_then_always_explode() throws Exception {
// setup omitted
try {
CodeWithPrivateMethod.startGamble();
}
catch(NullPointerException e) {
// expected
return;
}
fail("Expected NullPointerException");
}
EDIT: Testing multiple classes that call each other statically like this is a severe code smell. 编辑:测试多个这样静态调用彼此的类是一种严重的代码味道。 Unit tests should test a single class and inline static calls should be limited to utility classes.
单元测试应测试单个类,而内联静态调用应限于实用程序类。
Another comment: your example class names are very confusing. 另一个评论:您的示例类名称非常混乱。 Next time please stick with Foo, Bar, Baz or Appple, Pear, Banana.
下次,请坚持使用Foo,Bar,Baz或Appple,梨,香蕉。
If you are not getting an NPE then I expect your mocking/spying is interfering. 如果您没有获得NPE,那么我希望您的嘲笑/间谍活动会造成干扰。 If you call the code under test without mocking/spying the call chain would be:
如果您在不进行模拟/间谍的情况下调用受测代码,则调用链为:
CodeWithPrivateMethod.startGamble();
->
CodeWithYetAnotherPrivateMethod value = CodeWithAnotherPrivateMethod.getGambleValue();
->
return null;
<-
value.getGambling();
<- throws NullPointerException
What exactly are you trying to find out or achieve? 您到底想找出或实现什么?
EDIT: Here's how it should work with PowerMock 编辑:这是它应如何与PowerMock一起使用
@RunWith(PowerMockRunner.class)
@PrepareForTest(CodeWithAnotherPrivateMethod.class)
public class CodeWithPrivateMethodTest {
@Mock
private CodeWithYetAnotherPrivateMethod yetAnotherInstance;
@Test
public final void testStartGamble() {
// SETUP
mockStatic(CodeWithAnotherPrivateMethod.class);
expect(CodeWithAnotherPrivateMethod.getGambleValue())
.andReturn(yetAnotherInstance);
Boolean gamblingValue = true;
expect(yetAnotherInstance.getGambling()).andReturn(gamblingValue);
replayAll();
// CALL
CodeWithPrivateMethod.startGamble();
// VERIFY
verifyAll();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.