You are currently viewing How to Fix InvalidUseOfMatchersException In Java

How to Fix InvalidUseOfMatchersException In Java

1. Introduction

If you have ever written a Unit test using the mocking Framework Mockito, there is a big chance that you have already encountered this exception. In this quick tutorial, you will learn what the InvalidUseOfMatchersException is about and how to fix it.

2. What Mockito Says about InvalidUseOfMatchersException

As its name suggests, this exception occurs whenever you misuse the matchers in your code. Typically, this happens when you combine matchers and raw values in a test.

3. How to Reproduce

Consider the following class under test Calculator.java :

//Calculator.java
package com.kloudly.exception;

public class Calculator {
    private OperationFormatter formatter;
    public Calculator(OperationFormatter formatter){
        this.formatter = formatter;
    }
    public String calculate(double firstOperand, double secondOperand, char operator){
        double result = 0d;
        switch (operator){
            case '+':{
                result = add(firstOperand,secondOperand);
                return this.formatter.format(operator,firstOperand,secondOperand,result);
            }
            case '-':{
                result = subtract(firstOperand,secondOperand);
                return this.formatter.format(operator,firstOperand,secondOperand,result);
            }
            case '*':{
                result = multiply(firstOperand,secondOperand);
                return this.formatter.format(operator,firstOperand,secondOperand,result);
            }
            case ':':{
                result = divide(firstOperand,secondOperand);
                return this.formatter.format(operator,firstOperand,secondOperand,result);
            }
            default:
                throw new IllegalArgumentException("Unsupported operation :"+operator);
        }

    }

    private double divide(double firstOperand, double secondOperand) {
        if(secondOperand == 0)
            throw new IllegalArgumentException("Second argument must not be zero!");
        return firstOperand / secondOperand;
    }

    private double multiply(double firstOperator, double secondOperand) {
        return firstOperator * secondOperand;
    }

    private double subtract(double firstOperand, double secondOperand) {
        return firstOperand - secondOperand;
    }

    private double add(double firstOperand, double secondOperand) {
        return firstOperand + secondOperand;
    }
}

The Calculator class depends on another class OperationFormatter:

//OperationFormatter.java

package com.kloudly.exception;

public class OperationFormatter {

    public String format(char operator, double firstOperand, double secondOperand, double result){
        return firstOperand + " " + operator + " "+ secondOperand +" = " + result;
    }
}

Let’s assume we want to test the Calculator class in a Unit context. We will have to mock the OperationFormatter class.

Below is the code snippet of CalculatorTest class:

package com.kloudly.exception;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class CalculatorTest {
    private static Calculator calculator;
    private static OperationFormatter formatter;

    @BeforeAll
    static void setUp(){
        formatter = mock(OperationFormatter.class);
        calculator = new Calculator(formatter);
    }

    @Test
    public void testInvalidUseOfMatchers() {
        //Given
        String expectedResult = "1 + 1 = 2";
   when(formatter.format('+',anyDouble(),anyDouble(),anyDouble())).thenReturn(expectedResult);
        //When
        String result = calculator.calculate(1,1,'+');
        //Then
        assertEquals(expectedResult,result);
    }
}

If you run the CalculatorTest class, you will get the following output:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
4 matchers expected, 3 recorded:
-> at com.kloudly.exception.CalculatorTest.testInvalidUseOfMatchers(CalculatorTest.java:26)
-> at com.kloudly.exception.CalculatorTest.testInvalidUseOfMatchers(CalculatorTest.java:26)
-> at com.kloudly.exception.CalculatorTest.testInvalidUseOfMatchers(CalculatorTest.java:26)

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(any(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(any(), eq("String by matcher"));

For more info see javadoc for Matchers class.

This exception happens here because of this line : when(formatter.format('+',anyDouble(),anyDouble(),anyDouble())).thenReturn(expectedResult);

As you can see, we are combining the raw value '+' with the matcher anyDouble().

4. How to Fix the Exception

Ensure you are not mixing raw values and matchers in your mock configurations. For the test above, you must replace the raw value '+' with a matcher equivalent eq('+').

    @Test
    public void testInvalidUseOfMatchers() {
        //Given
        String expectedResult = "1 + 1 = 2";

        when(formatter.format(eq('+'),anyDouble(),anyDouble(),anyDouble())).thenReturn(expectedResult);
        //When
        String result = calculator.calculate(1,1,'+');
        //Then
        assertEquals(expectedResult,result);
    }

5. Conclusion

In this brief tutorial, you learned about the InvalidUseOfMatchersException and how to fix it. Learn more about Common Java Exception.
You can find the complete code of this article here in GitHub

Noel Kamphoa

Experienced software engineer with expertise in Telecom, Payroll, and Banking. Now Senior Software Engineer at Societe Generale Paris.

This Post Has One Comment

Comments are closed.