如何处理Mockito中不匹配的参数?

sup*_*sky 21 java junit mockito

我喜欢做以下的事情:

.when( 
    myMock.doSomething(
        Matchers.eq( "1" )
    ) 
)
.thenReturn( "1" )
.othwerwise()
.thenThrow( new IllegalArgumentException() );
Run Code Online (Sandbox Code Playgroud)

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

Cha*_*lie 21

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

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

JavaDoc的链接:的Mockito#模拟ThrowsExceptionClass

另外,如在讨论成株教程中,磕碰问题和最后一个匹配的顺序获胜,那么你也许可以也做:

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");
Run Code Online (Sandbox Code Playgroud)

  • ...所以在这种特殊情况下,你希望第二次调用是`doReturn("1").when(myMock).doSomething(Matchers.eq("1"));`甚至只是`doReturn( "1")时(myMock).doSomething( "1");` (7认同)
  • 几个警告.你给出的第一个解决方案是好的,但是因为默认的答案适用于模拟的_every_方法,如果你的测试也在你的模拟上调用了一些其他的方法,你需要小心,除了你的那个测试.我很确定你提供的第二个解决方案不起作用,因为第二次调用`doSomething`实际上会调用第一次调用中设置的行为,因此你将立即得到`IllegalArgumentException`.当你使用"doXxx"系列的存根方法时,"最后存根获胜"行为才会开始...... (6认同)
  • 这对我不起作用。第二个 `when()` 调用抛出异常。 (2认同)

Mat*_*att 9

你可以创建自己的Answer实现,它会关注被调用的参数:

myMock.doSomething(Mockito.any(String.class)).thenAnswer( myAnswer );
Run Code Online (Sandbox Code Playgroud)

所述答案的实施可以做到这样的事情:

public String answer(InvocationOnMock invocation) {
    if ("1".equals(invocation.getArguments()[0])) {
       return "1";
    }
    else {
       throw new IllegalArgumentException();
    }
} 
Run Code Online (Sandbox Code Playgroud)


Yog*_*ngh 5

只是使用相反的条件,即考虑你的例子本身.您可能希望not(eq())在需要时使用otherwise:

 .when( myMock.doSomething(Matchers.eq( "1" )))
     .thenReturn( "1" )
 .when( myMock.doSomething(not(Matchers.eq( "1" ))))
     .thenThrow( new IllegalArgumentException() );
Run Code Online (Sandbox Code Playgroud)