是否有可能以紧凑的方式使用Mockito验证任意交互?

时间:2012-06-25 15:20:32

标签: methods mocking call mockito

很容易验证Mockito中模拟对象上发生的特定交互(特定方法调用),并且verifyZeroInteractions()用于检查根本没有发生交互。假设我正在使用诸如info()warn()error()之类的方法测试诸如记录器之类的接口。在特定情况下,我知道应该调用其中一个方法,但我真的不在乎哪一个。是否有一种紧凑的方法来检查是否发生了与模拟对象的任何交互,而无需指定应该调用哪个确切的方法?或许也许这样的机制是不必要的,因为测试这种机制的“Mockito方式”会与我想象的不同?

2 个答案:

答案 0 :(得分:2)

使用log4j来测试记录器,我进行以下设置:

@Mock private Appender log4jAppender;
private Logger logger;

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);

    Logger root = Logger.getRootLogger();
    if (!root.getAllAppenders().hasMoreElements()) {
        // No appenders means log4j is not initialized!
        BasicConfigurator.configure();
    }
    logger = Logger.getLogger(MyClassWhichLogs.class);
    logger.addAppender(log4jAppender);
}

然后在我的测试中我执行以下操作:

verifyZeroInteractions(log4jAppender);

verify(log4jAppender).doAppend(any(LoggingEvent.class);

如果您需要测试记录的值,则可以改为使用捕获器:

ArgumentCaptor<LoggingEvent> logCaptor = ArgumentCaptor.forClass(LoggingEvent.class);
verify(log4jAppender).doAppend(logCaptor.capture());
assertTrue(logCaptor.getValue().contains("my text to match");

虽然这不一定能回答广义问题(我不认为你在寻找什么),但它可以解决测试记录的这个特定问题。

答案 1 :(得分:1)

如果您可以从被测试的类中外部化您的记录器对象的创建,那么您没有理由不编写自己的日志接口测试实现,该实现将记录已执行的方法并将其作为您的一部分注入测试设置。

模拟库有很多优点,但有时会出现像你发现的那些可能无法满足你需求的角落情况。

如果您编写自己的实现进行此类测试,并将其注入测试中的测试类,那么您可以在getCount() > 0

上断言
public class LoggerTestSupportImpl implements ILogger {

    private int count = 0;

    @Override
    public int getCount() {
        return count;
    }

    @Override
    public void info(String message) {
        count++;    
    }

    @Override
    public void warn(String message) {
        count++;    
    }   
}