Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock JPA repository's save method in unit tests

For example, I have this method in UserService:

  @Override   @Transactional   public UserDto create(UserDto userDto) {      User dbUser = userRepository.findOne(userDto.getId());      if (dbUser != null) {       throw new AuthException(AuthException.ErrorCode.DUPLICATE_USER_EXCEPTION);     }      User oneByLogin = userRepository.findOneByLogin(userDto.getLogin());     if (oneByLogin != null) {       throw new AuthExceptionAuthException.ErrorCode.DUPLICATE_LOGIN_EXCEPTION);     }      User newUser = new User();     newUser.setGuid(UUID.randomUUID().toString());     newUser.setInsertDate(new Date());     newUser.setFirstName(userDto.getFirstName());     newUser.setLastName(userDto.getLastName());     newUser.setLogin(userDto.getLogin());     newUser.setPassword(userDto.getPassword());     newUser.setAuthToken(TokenGenerator.nextToken());     newUser.setAuthTokenCreatedDate(new Date());      User savedUser = userRepository.save(newUser);      userDto.setAuthToken(savedUser.getAuthToken());     log.info("User {0} created", savedUser.getLogin());     return userDto;   } 

How can I create unit test for this method? I tried next:

  @Test   public void createUser() {      UserDto userDtoRequest = new UserDto();     userDtoRequest.setLogin("Alex");     userDtoRequest.setPassword("123");      UserDto found = userService.create(userDtoRequest);     assertThat(found.getAuthToken()).isNotEmpty(); } 

I have next logic:

  1. Test start
  2. User dbUser = userRepository.findOne(userDto.getId()); dbUser = NULL
  3. if (dbUser != null) and if (oneByLogin != null) skip
  4. create new user and set data
  5. User savedUser = userRepository.save(newUser); savedUser = NULL

On this step, I have a problem because I cannot mock userRepository.save(newUser).

newUser create inside the method. and test fail. 

savedUser.getAuthToken() - savedUser == NULL

I can rewrite:

    userRepository.save(newUser);     userDto.setAuthToken(newUser.getAuthToken());     log.info("User {0} created", newUser.getLogin());     return userDto; 

but what if I want to use the returned object savedUser?

like image 471
ip696 Avatar asked Jul 09 '18 14:07

ip696


People also ask

How do you write JUnit test cases for JPA repository?

You can create a @DataJpaTest and @Autowire your repository into it. For example: @RunWith(SpringRunner. class) @DataJpaTest public class MyJpaTest { @Autowired private ChartRepository chartRepository; @Test public void myTest() { ... } }

What is the return type of save method in JPA repository?

JPA's persist method returns void and Hibernate's save method returns the primary key of the entity.

What can be mocked with Mockito?

The Mockito. mock() method allows us to create a mock object of a class or an interface. We can then use the mock to stub return values for its methods and verify if they were called. We don't need to do anything else to this method before we can use it.


1 Answers

You need to do this.

when(userRepository.save(Mockito.any(User.class)))                 .thenAnswer(i -> i.getArguments()[0]); 

And now you can obtain user which you pass as argument.

like image 98
spajdo Avatar answered Oct 07 '22 12:10

spajdo