Steve
Steve

Reputation: 772

How to make Mockito arguments match method signature

I'm trying to validate that the correct message is logged by my code in an error condition, so I've mocked org.apache.commons.logging.Log and I'm trying to verify that it is called correctly.

The signature of the method I'm looking to verify is: error(Object, Throwable) I'm expecting to have a String passed in that has a variety of other things, but includes the text "Message is too big for queue". The throwable will be null in this case.

Here is my code to validate this:

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

When this runs, I get an error though:

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

It appears that the problem here is that that Mockito.matches() makes it look for a method with the signature (String, Throwable) when the actual signature is (Object,Throwable).

How can I make these match? I know the String is the problem because if I replace the Mockito.matches() with Mockito.any() it passes.

Upvotes: 4

Views: 2414

Answers (1)

unigeek
unigeek

Reputation: 2826

Maybe an example would help here. See if you can make sense of this. It may be somewhat contrived, but it should get you a little closer anyway..

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

Upvotes: 1

Related Questions