25

我喜欢做以下事情:

.when( 
    myMock.doSomething(
        Matchers.eq( "1" )
    ) 
)
.thenReturn( "1" )
.othwerwise()
.thenThrow( new IllegalArgumentException() );

当然otherwise()方法不存在,只是为了向您展示我想要完成的事情。

4

6 回答 6

24

(轻微的免责声明,我从来没有亲自做过,只是在javadoc中阅读过它)......如果你的模拟界面上的所有方法都可以使用相同的默认行为,你可以在你的模拟上设置默认答案以如下方式:

Foo myMock = Mockito.mock(Foo.class,new ThrowsExceptionClass(IllegalArgumentException.class));
Mockito.when(myMock.doSomething(Matchers.eq("1"))).thenReturn("1");

JavaDoc 链接:Mockito#mockThrowsExceptionClass

或者,正如Stubbing 教程中所讨论的,存根的顺序很重要,最后匹配获胜,所以你也可以这样做:

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");
于 2012-10-25T05:02:32.990 回答
9

您可以创建自己的 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();
    }
} 
于 2012-10-25T04:24:42.067 回答
5

只需使用相反的条件,即考虑您的示例本身。您可能需要not(eq())在需要时使用otherwise

 .when( myMock.doSomething(Matchers.eq( "1" )))
     .thenReturn( "1" )
 .when( myMock.doSomething(not(Matchers.eq( "1" ))))
     .thenThrow( new IllegalArgumentException() );
于 2012-10-25T03:57:14.697 回答
1

使用 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);
});
于 2016-03-01T16:26:25.643 回答
1

@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();

于 2018-01-18T13:57:08.560 回答
-1

或者,您可以使用验证,如下所示:

when(myMock.doSomething("1")).thenReturn( "1" );
assertEquals(myMock.doSomething("1"),"1");
verify(myMock).doSomething("1")
于 2013-12-05T22:47:36.540 回答