Home > other >  Is it possible to mock authentication with predefined arraylist as db?
Is it possible to mock authentication with predefined arraylist as db?

Time:05-18

I'm learning mock and I wonder if I could use a code similar as this:

Mockito.when(service.authenticateUser(test)).thenReturn(any());

to validate the success of authentication.

service.AuthenticateUser(User user):

@Override
public Player authenticateUser(User login) throws AuthenticationException {
    Player find = new Player();

    for (Player player : initializedPlayers) {
            if (login.getEmail().equals(player.getEmail()) && login.getPassword().equals(player.getPassword())) {

            loggedPlayer = player;
            return player;
            }
    }
    throw new AuthenticationException("Incorrect email and/or password");
}

As you can see, the login method returns a Player, but is there a possible way to tell Mockito that I only want to get something back, if its valid? So I would be able to test wheter the authentication was succesful or not, e.g.:

Mockito.when(service.authenticateUser(test)).thenReturn(any(Player.class));
    assertNotNull(service.authenticateUser(test));

^this method currently not working, it gives failed test on stub.

CodePudding user response:

You can't use any(...) in the thenReturn statement, that's where the error comes from.

This code should work:

Mockito.when(service.authenticateUser(test)).thenReturn(new Player(...));
assertNotNull(service.authenticateUser(test));

Now if you want to stub different results depending on the value of the login, you can use argumentMatchers in the when() part:

Mockito.when(service.authenticateUser(any(User.class))
  .thenThrow(AuthenticationException.class);
Mockito.when(service.authenticateUser(argThat(login -> list.contains(login))
  .thenReturn(new Player(...));

assertNotNull(service.authenticateUser(test));

Here the order is important: Mockito will try to match your argument in reverse order of stubs, so here it will first check if the login is in the given list, and if that stub fails, it will fall back to the first stub, which will throw an AuthenticationException for anything else.

If you want the returned Player to be dependent on the login User, you can use .thenAnswer() instead of .thenReturn(). See Mockito : doAnswer Vs thenReturn

CodePudding user response:

Mockito.when(service.authenticateUser(test)).thenReturn(any(Player.class));
assertNotNull(service.authenticateUser(test));

By mocking the return value of service.authenticateUser(test), you are testing Mockito, not your own code.

is there a possible way to tell Mockito that I only want to get something back, if its valid? So I would be able to test wheter the authentication was succesful or not

Don't use Mockito for this. Instead, you need to create a list of initializedPlayers and make it available to the authenticateUser() function. Ideally, you can just pass this list to the service object's constructor when you create it in your test. If not, then you have to create the players in a way that the service will get them when it needs to.

Similarly, you can create a test to verify that authenticateUser () throws AuthenticationException when the given user is not in the list of players.

  • Related