我有一个类,我想使用包含一些链式方法调用的公共(public)静态方法进行测试。假设在链式方法调用期间发生异常,我如何有效地处理该异常并使其返回某个特定值?
以下是测试类的代码示例。
@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();
}
}
以下是被测类的代码示例
public class CodeWithPrivateMethod {
public static void startGamble() {
Boolean gamble = CodeWithAnotherPrivateMethod.getGambleValue()
.getGambling();
if (gamble) {
System.out.println("kaboom");
}else{
System.out.println("boom boom");
}
}
}
以下是从被测类调用的类的代码示例
public class CodeWithAnotherPrivateMethod {
static CodeWithYetAnotherPrivateMethod codeWithYetAnotherPrivateMethod = new CodeWithYetAnotherPrivateMethod();
public static CodeWithYetAnotherPrivateMethod getGambleValue() {
return codeWithYetAnotherPrivateMethod; //works fine
return null; // fails
}
}
以下是从被测类调用的另一个类的代码示例
public class CodeWithYetAnotherPrivateMethod {
public Boolean getGambling() {
return false;
}
}
假设我从 CodeWithAnotherPrivateMethod 类的 getGambleValue() 方法返回一个空值,我如何在我的测试类中有效地处理这个空值?
最佳答案
这是使用 Mockito 指定预期异常的方法:
@Test(expected = NullPointerException.class)
public void when_gambling_is_true_then_always_explode() throws Exception {
...
在我发现这一点之前,我会这样做:
@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");
}
编辑:测试像这样静态地相互调用的多个类是一种严重的代码味道。单元测试应测试单个类,内联静态调用应仅限于实用程序类。
另一条评论:你的示例类名非常困惑。下次请坚持使用 Foo、Bar、Baz 或 Apple、Pear、Banana。
如果您没有获得 NPE,那么我预计您的 mock / spy 行为会造成干扰。如果您在不模拟/监视的情况下调用被测代码,则调用链将是:
CodeWithPrivateMethod.startGamble();
->
CodeWithYetAnotherPrivateMethod value = CodeWithAnotherPrivateMethod.getGambleValue();
->
return null;
<-
value.getGambling();
<- throws NullPointerException
您到底想找出或实现什么?
编辑:这是它应该如何与 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();
}
关于java - 使用 PowerMock 模拟链式方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35574111/