Peter Santesson
Peter Santesson

Reputation: 23

Using same ArgumentMatchers in Mockito.when multiple times

I've been learning about tests lately but this is the first test were I've had to pass a variable in a function that I'm mocking. I've written a similar test were the only difference is that i use an ArgumentMatcher in this test because the testInput.validate() needs 3 Strings to pass with it. I don't know this stuff very well so I'm sorry if the terminology is off.

Here is the code i'm trying to test:

@Component
public class RequestHandler {

private static Gson gson = new Gson();
private final UserRepository userRepository;
private final TestInput testInput;

@Autowired
public RequestHandler(UserRepository userRepository, TestInput testInput) {
    this.userRepository = UserRepository;
    this.testInput = testInput;
}

public String addUser(String username, String email, String password) {
    if (testInput.validate(username, email, password) && !(userRepository.findById(email).isPresent())) {
        User user = new User(username, email, password);
        userRepository.save(user);
        return gson.toJson(user);
    } else {
        return gson.toJson("error");
    }
  }
}

And here is my test:

public class RequestHandlerTest {
    UserRepository userRepository = Mockito.mock(UserRepository.class);
    TestInput testInput = Mockito.mock(TestInput.class);

    RequestHandler requestHandler = new RequestHandler(userRepository, testInput);

    String test = ArgumentMatchers.anyString();

    @Test
    public void addUserTest() {
        Mockito.when(testInput.validate(test, test, test)).thenReturn(true, false); 

        Mockito.when(userRepository.findById(test).isPresent()).thenReturn(false, true);

        String jsonUser = new Gson().toJson(new User("username123","[email protected]","12344321"));
        String jsonError = new Gson().toJson("error");

        System.out.println("addUser Test1");
        assertEquals(jsonUser, requestHandler.addUser("username123","[email protected]","12344321"));

        System.out.println("addUser Test2");
        assertEquals(jsonError, requestHandler.addUser("username123","[email protected]","12344321"));
    }
}

I had a bunch of errors with this code and when I changed the ArgumentMatchers.anyString() to just ArgumentMatchers.any() I had 1 error instead of like 5.

Upvotes: 1

Views: 953

Answers (2)

Razumain
Razumain

Reputation: 71

I looked into the source code of this problem, and for information to other readers, the underlying problem was that the mocked function was declared "static". This is not evident from the posted problem.

Upvotes: 1

pvpkiran
pvpkiran

Reputation: 27078

There are many issues in your test.

  1. You cannot use like this

    String test = ArgumentMatchers.anyString();
    Mockito.when(testInput.validate(test, test, test)).thenReturn(true, false); 
    

    You can clearly see from the error message what Mockito is saying when you do this

    org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
    Invalid use of argument matchers!
    3 matchers expected, 1 recorded:
    

    which means you need to pass three different instances.

  2. This line is also not correct

    Mockito.when(userRepository.findById(test).isPresent()).thenReturn(false, true);
    

findById should return Optional, but you are returning boolean. When you use Mockito, you should mock individual steps. What I mean is in your example you need to mock userRepository.findById(test) and then isPresent on that returned mock. You cannot skip one step and go to the next.

Here is a working code

public class RequestHandlerTest {
    UserRepository userRepository = Mockito.mock(UserRepository.class);
    TestInput testInput = Mockito.mock(TestInput.class);

    RequestHandler requestHandler = new RequestHandler(userRepository, testInput);

    @Test
    public void addUserTest() {
        when(testInput.validate(anyString(), anyString(), anyString())).thenReturn(true, false);


        User username123 = new User("username123", "[email protected]", "12344321");
        String jsonUser = new Gson().toJson(username123);
        String jsonError = new Gson().toJson("error");


        when(userRepository.findById(anyString())).thenReturn(Optional.empty(),Optional.of(username123));
        System.out.println("addUser Test1");
        assertEquals(jsonUser, requestHandler.addUser("username123","[email protected]","12344321"));

        System.out.println("addUser Test2");
        assertEquals(jsonError, requestHandler.addUser("username123","[email protected]","12344321"));
    }
}

Upvotes: 0

Related Questions