请参见此示例:
class Foo { }
class Bar {
void takeIt(int i, String arg) { System.out.println(arg + i); }
}
public class Mcve {
@Test
public void passes() {
Foo foo = Mockito.mock(Foo.class);
Bar bar = Mockito.mock(Bar.class);
bar.takeIt(42, "surprise: " + foo);
String substring = "surprise: " + foo;
Mockito.verify(bar).takeIt(ArgumentMatchers.eq(42),
ArgumentMatchers.contains(substring));
}
@Test
public void fails() {
Foo foo = Mockito.mock(Foo.class);
Bar bar = Mockito.mock(Bar.class);
bar.takeIt(42, "surprise: " + foo);
Mockito.verify(bar).takeIt(ArgumentMatchers.eq(42),
ArgumentMatchers.contains("surprise: " + foo));
}
}
这两个测试几乎相同,唯一的区别是:用于 contains()
匹配器是在 passes()
,但内联在 fails()
. fails()
呕吐:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
0 matchers expected, 1 recorded:
-> at com.ibm.hwmca.z.svm.zhyp.managed.Mcve.fails(Mcve.java:43)
This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
For more info see javadoc for Matchers class.
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at Mcve.fails(Mcve.java:43)
...
(显然:错误消息是完全错误的,因为上面的代码对所有参数都使用匹配器)
更有趣的是:它只有一个以上的参数匹配失败(如果删除 int
参数来自 gimme()
,并只传递/匹配该字符串参数:pass)。
有没有人能解释一下这里到底发生了什么,有没有办法做到这样的匹配呢 contains("surprise: " + foo)
,与 foo
被人嘲笑?
当然,这是真正意义上的mcve。从我们环境中失败的单元测试到这里的示例,我花了3个小时。
在真实环境中,bar类是模拟的日志记录工具。而foo对象表示由某个伪持久层创建的某个“数据实体”。我必须验证生产代码是否记录了特定的信息,其中一些信息来自伪造的数据对象。
暂无答案!
目前还没有任何答案,快来回答吧!