为什么mockito在验证另一个mock时访问一个mock时会呕吐?

yhuiod9q  于 2021-07-09  发布在  Java
关注(0)|答案(0)|浏览(292)

请参见此示例:

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对象表示由某个伪持久层创建的某个“数据实体”。我必须验证生产代码是否记录了特定的信息,其中一些信息来自伪造的数据对象。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题