Is it possible to check arbitrary interaction with Mockito in a compact way?

It is easy to verify that a specific interaction (calling a special method) occurred on a mock object in Mockito, and exists verifyZeroInteractions()to verify that no interactions have occurred at all. Suppose that I'm testing an interface, such as a log, with techniques such as info(), warn(), error(), etc. In a specific scenario, I know that one of these methods should be called, but I am not really caring which one. Is there a compact way to verify that any interaction with a mock object happened without the need to indicate which method should be called? Or perhaps such a mechanism is not needed, because the โ€œMockito methodโ€ of testing this will be different from what I imagine?

+5
source share
2 answers

If you can disrupt the creation of your log object from the tested class, there is no reason why you cannot write your own test implementation of the log interface that will record what methods were executed and enter it as part of your test setup.

Dummy libraries do a lot of good, but sometimes there are corner cases like you find where they might not cover your needs.

If you write your own implementation for testing as follows and enter it in the test class test, then you can argue for 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++;    
    }   
}
+1
source

With log4j, to check the logger, I do the following setup:

@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);
}

and then in my test I do the following:

verifyZeroInteractions(log4jAppender);

or

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

If you need to test the registered values, you can provide instead:

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

( , ), .

+2

All Articles