Java 如何处理;任何其他价值”;和莫基托?

Java 如何处理;任何其他价值”;和莫基托?,java,mockito,Java,Mockito,我有一个带有方法intfoo.bar(int)的接口Foo,我想用Mockito模拟它。如果传入1,我希望模拟方法返回99,但所有其他值都将抛出异常。我能做这个吗 final Foo foo = mock(Foo.class); when(foo.bar(1)).thenReturn(99); when(foo.bar(anyInt())).thenThrow(new IllegalArgumentException()); 换句话说,1是否优先于anyInt()?我不希望它为1抛出异常。他们

我有一个带有方法
intfoo.bar(int)
的接口
Foo
,我想用Mockito模拟它。如果传入
1
,我希望模拟方法返回
99
,但所有其他值都将抛出异常。我能做这个吗

final Foo foo = mock(Foo.class);
when(foo.bar(1)).thenReturn(99);
when(foo.bar(anyInt())).thenThrow(new IllegalArgumentException());

换句话说,
1
是否优先于
anyInt()
?我不希望它为
1
抛出异常。他们说,对于多个定义,最后一个定义更为重要,但我不知道这是否意味着相同的参数。如果它适用于这里,我是否需要首先定义通配符
anyInt()
?或者两者之间有关系吗,因为其中一个是匹配器,另一个只是一个值?

您有两个选项:匹配“除一之外的任何值”和覆盖存根。(我想你也可以对复杂的定制行为使用一个答案,但对于像这样的情况来说,这太过分了。)

存根除给定值外的任何值 Mockito的类提供了许多有用的匹配器,包括运算符,例如。这将允许您为除特定值(或表达式)之外的所有值设置行为

请注意,运算符必须与匹配器而不是值一起使用,可能需要将
匹配器.eq
作为显式
等于
匹配器,因为Mockito的:

覆盖短截线 对于存根,最后定义的匹配链获胜。这允许您在
@Before
方法中设置常规测试夹具行为,并根据需要在单个测试用例中重写它,但也意味着顺序在存根调用中很重要

when(foo.baz(anyInt())).thenReturn("A", "B");  /* or .thenReturn("A").thenReturn("B"); */
when(foo.baz(9)).thenReturn("X", "Y");

foo.baz(6); /* "A" because anyInt() is the last-defined chain */
foo.baz(7); /* "B" as the next return value of the first chain */
foo.baz(8); /* "B" as Mockito repeats the final chain action forever */

foo.baz(9); /* "X" because the second chain matches for the value 9 */
foo.baz(9); /* "Y" forever because the second chain action still matches */
因此,您不应该按照问题中列出的顺序看到两个存根,因为如果一个常规匹配紧跟在一个特定匹配之后,那么该特定匹配将永远不会被使用(也可能被删除)

请注意,在重写间谍或危险的存根行为时,有时需要将语法更改为
doAnswer
。Mockito知道在
进行验证或沿着
thenVerb
链前进时,不计算对
的调用,但异常仍然可能导致测试失败

/* BAD: the call to foo.bar(1) will throw before Mockito has a chance to stub it! */
when(foo.bar(anyInt())).thenThrow(new IllegalArgumentException());
when(foo.bar(1)).thenReturn(99);

/* GOOD: Mockito has a chance to deactivate behavior during stubbing. */
when(foo.bar(anyInt())).thenThrow(new IllegalArgumentException());
doReturn(99).when(foo).bar(1);

这是一个很好的问题,我在文档或博客中都找不到关于如何实现你想要的(+1)。也许可以帮助你,尽管你可以在杰夫的回答中看到不同的选择(+1)杰夫·鲍曼说:“如果一场普通比赛紧接着一场特定比赛,那么该特定比赛将永远不会被使用……”。你的意思是“如果一场普通的比赛之后紧接着一场特殊的比赛……”吗?加勒特:不,我的意思是这样的。最新定义的匹配链获胜,因此,如果您进行了特定匹配,然后按照问题中的说明进行了更一般的匹配,则一般匹配将是最新的匹配链,并且特定行为将被有效删除,这听起来不是您想要的行为。明白了。这在今天是有意义的,但昨天出于某种原因,我的大脑分析了这个句子,使其意思正好相反。不知道为什么。谢谢你的回复。
when(foo.baz(anyInt())).thenReturn("A", "B");  /* or .thenReturn("A").thenReturn("B"); */
when(foo.baz(9)).thenReturn("X", "Y");

foo.baz(6); /* "A" because anyInt() is the last-defined chain */
foo.baz(7); /* "B" as the next return value of the first chain */
foo.baz(8); /* "B" as Mockito repeats the final chain action forever */

foo.baz(9); /* "X" because the second chain matches for the value 9 */
foo.baz(9); /* "Y" forever because the second chain action still matches */
/* BAD: the call to foo.bar(1) will throw before Mockito has a chance to stub it! */
when(foo.bar(anyInt())).thenThrow(new IllegalArgumentException());
when(foo.bar(1)).thenReturn(99);

/* GOOD: Mockito has a chance to deactivate behavior during stubbing. */
when(foo.bar(anyInt())).thenThrow(new IllegalArgumentException());
doReturn(99).when(foo).bar(1);