Ruslan
Ruslan

Reputation: 197

Return different values from mock, depending on args

I'm trying to make mock that should return different value if the argument had concrete class. I created tableVerificationService mock object and created these when conditions.

Mockito.when(tableVerificationService.verify(Mockito.any())).thenReturn(true);
Mockito.when(tableVerificationService.verify(Mockito.any(DTable.class))).thenReturn(false);

But now it returns false in any case, even if i pass another from DTable object.

If i change order of these two lines, it will return true in all cases. Is there any way to make correct behavior?

Upvotes: 1

Views: 1189

Answers (1)

rieckpil
rieckpil

Reputation: 12021

You can use .thenAnswer() or .then() (shorter) to have more control of the returned value.

An example might visualize this better.

Let's assume we want to mock the Java class:

public class OtherService {

  public String doStuff(String a) {
    return a;
  }
}

... and we want to return "even" if the passed String is even and "uneven" otherwise.

By using .then() we get access to the InvocationOnMock and can access the passed argument. This helps to determine the returned value:

class MockitoExampleTest {

  @Test
  void testMe() {

    OtherService otherService = Mockito.mock(OtherService.class);

    when(otherService.doStuff(ArgumentMatchers.anyString())).then(invocationOnMock -> {
      String passedString = invocationOnMock.getArgument(0);

      if (passedString.length() % 2 == 0) {
        return "even";
      } else {
        return "uneven";
      }
    });

    System.out.println(otherService.doStuff("duke")); // even
    System.out.println(otherService.doStuff("egg")); // uneven

  }
}

With this technique you can check the passed argument and determine if it's your concrete class and then return whatever value you want.

Upvotes: 2

Related Questions