【问题标题】:How to make Mockito arguments match method signature如何使 Mockito 参数匹配方法签名
【发布时间】:2016-09-20 21:42:07
【问题描述】:

我正在尝试验证我的代码是否在错误条件下记录了正确的消息,因此我模拟了 org.apache.commons.logging.Log 并尝试验证它是否被正确调用。

我要验证的方法的签名是:error(Object, Throwable) 我希望传入一个包含各种其他内容的字符串,但包含文本“消息对于队列来说太大了”。在这种情况下,throwable 将为 null。

这是我的验证代码:

Mockito.verify(errorLog, Mockito.atLeastOnce()).error(
     Mockito.matches("*Message is too big for queue*"),
     Mockito.isNull(Throwable.class)); 

当它运行时,我得到一个错误:

Argument(s) are different! Wanted:
log.error(
    matches("*Message is too big for queue*"),
    isNull()
);
-> at com.company.TestClass.testMessageTooBig(TestClass.java:178)
Actual invocation has different arguments:
log.error(
    |ClassUnderTest|Message is too big for queue (size=41). It will never fit, so discarding.,
    null
);

这里的问题似乎是Mockito.matches() 在实际签名为 (Object,Throwable) 时使其查找具有签名 (String, Throwable) 的方法。

我怎样才能使这些匹配?我知道字符串是问题所在,因为如果我将 Mockito.matches() 替换为 Mockito.any() 它就会通过。

【问题讨论】:

  • 如果您从 Mockito.matches 的参数中删除前导星号和尾随星号会发生什么?我在想这可能会使正则表达式匹配。
  • ArgumentCaptor 可能是您的选择
  • 我试过 ArgumentCaptor 但没有帮助:Argument(s) are different! Wanted: log.error( org.mockito.ArgumentCaptor@7ce3cb8e, null );
  • 同样删除星号:Argument(s) are different! Wanted: log.error( matches("Message is too big for queue"), isNull() );
  • 这是另一个细节——我完全摆脱了匹配器:Mockito.verify(errorLog, Mockito.atLeastOnce()).error( (Object) "|ClassUnderTest|Message is too big for queue (size=41). It will never fit, so discarding.", null); 即使删除了匹配器,它仍然失败:参数不同!需要:log.error("|ClassUnderTest|消息对于队列来说太大了 (size=41)。它永远装不下,所以丢弃。", null);

标签: java unit-testing mocking mockito


【解决方案1】:

也许这里有一个例子会有所帮助。看看你能不能理解这一点。这可能有点做作,但无论如何它应该让你更接近一点..

Main.java

package com.company;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Main {
    private static Log log = LogFactory.getLog(Main.class);

    public Main(Log l) {
        this.log = l;
    }

    public static void main(String[] args) {
        Main m = new Main(log);
        m.go();
    }

    public void go() {
        log.info("this is a test of the emergency broadcasting system.", null);
    }
}

MainTest.java

package com.company;

import org.apache.commons.logging.Log;
import org.junit.Test;
import org.mockito.Mockito;

import static org.mockito.Matchers.*;

public class MainTest {
    Log mockLogger = (Log) Mockito.mock(Log.class);

    private Main testSubject = new Main(mockLogger);

    @Test
    public void should_use_logger() {
        //Mockito.doNothing().when(mockLogger).info(anyString(), any());
        testSubject.go();
        Mockito.verify(mockLogger, Mockito.times(1)).info(contains("emergency broadcasting"), isNull(Throwable.class));
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多