gpt4 book ai didi

java - 如何使用 Mockito 处理 "any other value"?

转载 作者:IT老高 更新时间:2023-10-28 20:41:23 25 4
gpt4 key购买 nike

我有一个接口(interface) Foo 和方法 int Foo.bar(int) 我想用 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 抛出异常。 docs说对于多个定义,最后一个定义更重要,但我不知道这是否意味着相同的论点。如果在这里适用,我需要先定义通配符 anyInt() 吗?或者两者是否有任何关系,因为其中一个是匹配器,另一个只是一个值?

最佳答案

您有两个选择:匹配“除一个之外的任何值”,以及覆盖 stub 。 (我想您也可以将 Answer 用于复杂的自定义行为,但对于这种情况来说,这太过分了。)

stub 除给定值之外的任何值

Mockito 的 AdditionalMatchers类提供了许多有用的匹配器,包括 not 等运算符.这将允许您为除特定值(或表达式)之外的所有值设置行为。

when(foo.bar(1)).thenReturn(99);
when(foo.bar(not(eq(1)))).thenThrow(new IllegalArgumentException());

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

/* BAD */  when(foo.bar(not(  1  ))).thenThrow(new IllegalArgumentException());
/* GOOD */ when(foo.bar(not(eq(1)))).thenThrow(new IllegalArgumentException());

覆盖 stub

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

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 */

因此,您永远不会看到问题中列出的顺序中的两个 stub ,因为如果一般匹配紧跟特定匹配,则永远不会使用特定匹配(也可能被删除)。

请注意,在覆盖 spy 或危险的 stub 行为时,您有时需要将语法更改为 doAnswer。 Mockito 知道不计算对 when 的调用以进行验证或沿 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);

关于java - 如何使用 Mockito 处理 "any other value"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34171082/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com