Login test always returns empty Optional (Spring Boot)

69 views Asked by At

i´m making a test for a very simple service login method, but I always get an empty Optional, when i should recieve an object. I´ve tried eevery part of the test, the "when"s are working as expected, it´s only the call to the loginUser method that returns an empty Optional. If i make a request through postman, it works just fine! i´m out of ideas as to what´s going on, does anyone have any clue?

The test:

  @Test
  public void testIfUserLogsIn() {
    LoginDTO loginDTO = new LoginDTO("[email protected]", "password");

    User testUser = new User(1L, "testname", "testlastname", "[email protected]", "password", USER, 
1111111111L, "testAdress", "testCity");
    when(this.userRepositoryTest.findByEmail(loginDTO.getEmail()))
            .thenReturn(Optional.of(testUser));
    when(this.passwordEncoder.matches(loginDTO.getPassword(), testUser.getPassword())).thenReturn(true);

    Optional<User> result = this.userServiceTest.loginUser(loginDTO);

    assertThat(result).isPresent();
  }

The loginUser method in my userService:

  public Optional<User> loginUser(LoginDTO loginDTO) {
    Optional<User> doesUserExists = this.userRepository.findByEmail(loginDTO.getEmail());
    if (doesUserExists.isPresent()) {
      if (passwordEncoder.matches(loginDTO.getPassword(), doesUserExists.get().getPassword())) {
        return doesUserExists;
      }
    }
    return Optional.empty();
  }

Here are the Mocks:

@ExtendWith(MockitoExtension.class)
public class UserServiceTest {

  @Mock
  private UserService userServiceTest;
  @Mock
  private UserRepository userRepositoryTest;
  @InjectMocks
  private UserController userController;
  @Mock
  private PasswordEncoder passwordEncoder;
1

There are 1 answers

0
knittl On

Your UserService is mocked:

@Mock
private UserService userServiceTest;

That means its real implementation will not be called. The mock will only do what you tell it to do – and you didn't tell it to do anything. So what happens? Mockito sets up the mock to return the default values for each respective return type (0 for numbers, false for boolean, empty collections for collections, absent optionals for optionsal, and null for strings and anything else).

If you want to exercise UserService in your test, you must not mock it, but use the actual implementation of it. Either new it up manually or have @InjectMocks create an instance of it and pass the other mocks.