【发布时间】:2012-10-25 03:44:43
【问题描述】:
我喜欢做以下事情:
.when(
myMock.doSomething(
Matchers.eq( "1" )
)
)
.thenReturn( "1" )
.othwerwise()
.thenThrow( new IllegalArgumentException() );
当然otherwise() 方法不存在,只是为了向您展示我想要完成的工作。
【问题讨论】:
我喜欢做以下事情:
.when(
myMock.doSomething(
Matchers.eq( "1" )
)
)
.thenReturn( "1" )
.othwerwise()
.thenThrow( new IllegalArgumentException() );
当然otherwise() 方法不存在,只是为了向您展示我想要完成的工作。
【问题讨论】:
(轻微的免责声明,我从未亲自做过,只是在 javadoc 中阅读过)...如果您的模拟接口上的所有方法都可以使用相同的默认行为,您可以 set the default answer on your mock in像这样的方式:
Foo myMock = Mockito.mock(Foo.class,new ThrowsExceptionClass(IllegalArgumentException.class));
Mockito.when(myMock.doSomething(Matchers.eq("1"))).thenReturn("1");
JavaDoc 链接:Mockito#mock 和 ThrowsExceptionClass
或者,正如Stubbing tutorial 中所讨论的,存根的顺序很重要,最后匹配的获胜,所以你也可以这样做:
Foo myMock = Mockito.mock(Foo.class);
Mockito.when(myMock.doSomething(Matchers.any(String.class))).thenThrow(IllegalArgumentException.class);
Mockito.when(myMock.doSomething(Matchers.eq("1"))).thenReturn("1");
【讨论】:
doSomething 的第二次调用实际上会调用在第一次调用中设置的行为,因此您将立即获得IllegalArgumentException。 “最后一个存根获胜”行为仅在您使用“doXxx”系列存根方法时才会出现......
doReturn("1").when(myMock).doSomething(Matchers.eq("1")); 甚至只是 doReturn("1").when(myMock).doSomething("1");
when() 调用抛出异常。
您可以创建自己的 Answer 实现,它会注意被调用的参数:
myMock.doSomething(Mockito.any(String.class)).thenAnswer( myAnswer );
上述答案的实现可以这样做:
public String answer(InvocationOnMock invocation) {
if ("1".equals(invocation.getArguments()[0])) {
return "1";
}
else {
throw new IllegalArgumentException();
}
}
【讨论】:
只需使用相反的条件,即考虑您的示例本身。当您需要otherwise 时,您可能想使用not(eq()):
.when( myMock.doSomething(Matchers.eq( "1" )))
.thenReturn( "1" )
.when( myMock.doSomething(not(Matchers.eq( "1" ))))
.thenThrow( new IllegalArgumentException() );
【讨论】:
while 没有任何 otherwise。 while 的语法是:满足条件时做某事。同样在这里。我们安排我们的 Java 代码来处理我们的需求。我们需要在这里应用类似的概念。
when 与 Java 中的 while 完全相同。我说过,when 的主体在满足条件时执行,与 while 的主体基于条件相同。我试图解释相似之处只是为了解释这里没有别的。 while 仅用于示例。我不确定分歧在哪里。还有其他构造可以用来实现您正在寻找的东西。
使用 java 8 lambda,您可以:
myMock.doSomething(Mockito.any(String.class)).thenAnswer(invocation -> {
Object arg = invocation.getArguments()[0];
if ("1".equals(arg)) {
return "1";
}
throw new IllegalArgumentException("Expected 1 but got " + arg);
});
【讨论】:
@Charlie 接受的答案所描述的方式不再起作用。 当您尝试覆盖某些参数的一般抛出异常行为时,会触发第一个规则并且您遇到异常(正如您所要求的那样)。
Mockito.when(myMock.doSomething(any()))
.thenThrow(IllegalArgumentException.class);
Mockito.when(myMock.doSomething(eq("1"))).thenReturn("1"); //An exception is thrown here
// because of the call to .doSomething() on the mock object
为了避免调用,可以使用Mockito.doReturn() 方法:
Mockito.when(myMock.doSomething(any()))
.thenThrow(IllegalArgumentException.class);
Mockito.doReturn("1").when(myMock).doSomething(eq("1"));
最初的问题是 doReturn() 根据它的 javadoc 存在的原因之一:
Here are those rare occasions when doReturn() comes handy:
<...some lines are skipped...>
Overriding a previous exception-stubbing:
hen(mock.foo()).thenThrow(new RuntimeException());
//Impossible: the exception-stubbed foo() method is called so RuntimeException is thrown.
when(mock.foo()).thenReturn("bar");
//You have to use doReturn() for stubbing:
doReturn("bar").when(mock).foo();
【讨论】:
您也可以使用verify,如下:
when(myMock.doSomething("1")).thenReturn( "1" );
assertEquals(myMock.doSomething("1"),"1");
verify(myMock).doSomething("1")
【讨论】: