I'm currently on a course learning Spring-boot and I'm stuck with testing a project - any help is much appreciated as I'm a beginner here.
I have a rest controller test, using Mockito that appears to be ignoring "ThenReturn" when a method is invoked using Mockito.when().
Here is the whole class:
package com.example.demo.controllers;
import com.example.demo.TestUtils;
import com.example.demo.model.persistence.AppUser;
import com.example.demo.model.persistence.repositories.CartRepository;
import com.example.demo.model.persistence.repositories.UserRepository;
import com.example.demo.model.requests.CreateUserRequest;
import org.junit.Before;
import org.junit.Test;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import java.util.Optional;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
public class UserControllerTest {
private UserController userController;
private UserRepository userRepository = mock(UserRepository.class);
private CartRepository cartRepository = mock(CartRepository.class);
private BCryptPasswordEncoder bCryptPasswordEncoder = mock(BCryptPasswordEncoder.class);
@Before
public void initTest(){
userController = new UserController();
TestUtils.injectObjects(userController, "userRepository", userRepository);
TestUtils.injectObjects(userController, "cartRepository", cartRepository);
TestUtils.injectObjects(userController, "bCryptPasswordEncoder", bCryptPasswordEncoder);
AppUser appUser = TestUtils.getAppUser();
when(userRepository.findById(0L)).thenReturn(Optional.of(appUser));
when(bCryptPasswordEncoder.encode("testPassword")).thenReturn("hashedPassword");
}
@Test
public void testFindUserById(){
ResponseEntity<AppUser> response = userController.findById(0L);
System.out.println(response);
}
@Test
public void testCreateUser() throws Exception{
CreateUserRequest createUserRequest = new CreateUserRequest();
createUserRequest.setUsername("testUser");
createUserRequest.setPassword("testPassword");
createUserRequest.setConfirmPassword("testPassword");
ResponseEntity<AppUser> response = userController.createUser(createUserRequest);
assertNotNull(response);
assertEquals(200, response.getStatusCodeValue());
AppUser createdUser = response.getBody();
assertNotNull(createdUser);
assertEquals(0, createdUser.getId());
assertEquals("testUser", createdUser.getUsername());
assertEquals("hashedPassword", createdUser.getPassword());
}
}
The test called "testCreateUser" passes without a problem. It's the test called "testFindUserById" that is giving me a problem.
Here is the controller method I'm trying to test (all working fine when tested in Postman):
public ResponseEntity<AppUser> findById(@PathVariable Long id) {
try{
log.info("UserIDSearch = " + id);
System.out.println("UserIDSearch = " + id);
Optional<AppUser> optionalAppUser = userRepository.findById(id);
if(optionalAppUser.isPresent()){
log.info("UserIdFound = " + id);
return ResponseEntity.ok(optionalAppUser.get());
}else{
throw new ApiException(ExceptionTypes.SEARCHUSER, id.toString());
}
}catch(ApiException a){
return ResponseEntity.notFound().build();
}
}
The repository being mocked in the test class is just a straightforward JpaRepository:
public interface UserRepository extends JpaRepository<AppUser, Long> {
Optional<AppUser> findByUsername(String username);
public Optional<AppUser> findById(long id);
}
The output I get from running the testFindUserById() test is the following:
UserIDSearch = 0
<404 NOT_FOUND Not Found,[]>
I guess what I'm trying to achieve here is that the test uses the when().thenReturn() to simulate an OK response from the mocked userRepository, but instead it actually performs the search and returns the "Not found". Can anyone help? Thanks so much!
thenReturn(Optional.of(appUser))part and actually performs the search on the repository - I have no idea why. A bit like when thetestCreateUser()method simulates returning a password from thebCryptPasswordEncoder, I'm trying to get thetestFindUserByIdmethod to simulate returning a user from the repository. - Matt ChermsideOptional<AppUser> optionalAppUser = userRepository.findById(id);and just returnOptional.of(appUser)which can be used to build the ReponseEntity returned by the controller method.But that's not happening. - Matt Chermside