javaunit-testingjunitmockitoargument-matcher

Mocking method behaviour based on the field of the parameter Java 8


I have a class definition as follows:

public class MyClass {

    public performExecution(ParamsClass paramsClassObject);
}

public ParamsClass {
    private String field1;
    private String field2;
}

Now, I want to mock the method performExecution based on the field1, but there is no direct way to do it even with the ArgumentMatchers.

Suppose I mocked the class:

MyClass myClass = mock(MyClass.class)

Now, I want to perform something like this: when the Params object passed in myClass.performExecution() has the field1 value as "1", then give a certain response, otherwise some other response.

Is that a way to do that ?


Solution

  • There are a couple of options:

    Option 1: Custom argument matcher

    See for example Custom Argument Matcher by baeldung

    Option 2: when / thenAnswer

    @Test
    void testThenAnswer() {
        MyClass myCollaborator = Mockito.mock(MyClass.class);
        when(myCollaborator.performExecution(any(ParamsClass.class)))
                .thenAnswer((invocationOnMock -> {
            ParamsClass params = invocationOnMock.getArgument(0);
            return "f1".equals(params.getField1())
                    ? "V1"
                    : "V2";
        }));
    
        var result = myCollaborator.performExecution(new ParamsClass("f1", "f2"));
        Assertions.assertThat(result).isEqualTo("V1");
    }
    

    Option 3: argThat Matcher

    @Test
    void testArgThat() {
        MyClass myCollaborator = Mockito.mock(MyClass.class);
        when(myCollaborator.performExecution(Mockito.argThat(p -> p != null && "f1".equals(p.getField1())))).thenReturn("V1");
        when(myCollaborator.performExecution(Mockito.argThat(p -> p != null && !"f1".equals(p.getField1())))).thenReturn("V2");
    
        var result = myCollaborator.performExecution(new ParamsClass("f1", "f2"));
        Assertions.assertThat(result).isEqualTo("V1");
    }
    

    Note null checks in argThat matchers