Prashant Mishra
Prashant Mishra

Reputation: 319

How do I mock an optional class in java?

I was mocking my crud app and I was trying to mock the update API. As findById() method belongs to Optional class, I can't find a way to mock it. Here is the code snippet.

@Mock
@Autowired
private UserRepository repo;

@Test
public void testUpdateUser() {
    Integer userId = 3;

    Optional<User> optionalUser = repo.findById(userId);

    User user = optionalUser.get();
    user.setFirstName("Paul");
    repo.save(user);

    User updatedUser = repo.findById(userId).get();
    Assertions.assertThat(updatedUser.getFirstName()).isEqualTo("Paul");
}

Upvotes: 1

Views: 6552

Answers (2)

ramazankul
ramazankul

Reputation: 472

Optional class is a final class, so you cannot mock this class with Mockito. You should use PowerMockito. I add below a sample code. Please try this.

@RunWith(PowerMockRunner.class)
@PrepareForTest(Optional.class)
public class PowerMockitoExample {


    @Mock
    Optional<User> optionalMock;

    @Mock Repository repo;

    @Test
    public void testUpdateUser() {
    
      //edit your mock user
      User yourUserData = null;
      
      Mockito.when(repo.findById(Matchers.anyInt())).thenReturn(optionalMock);
      PowerMockito.when(optionalMock.get()).thenReturn(yourUserData);
    
      Integer userId = 3;

      Optional<User> optionalUser = repo.findById(userId);

      User user = optionalUser.get();
      user.setFirstName("Paul");
      repo.save(user);

      User updatedUser = repo.findById(userId).get();
      Assertions.assertThat(updatedUser.getFirstName()).isEqualTo("Paul");
}

}

Upvotes: 2

Harry Coder
Harry Coder

Reputation: 2740

@Mock
@Autowired
private UserRepository repo;

This part of your code can lead to confusion. The principle behind mocking is to create a mock objects that is used by the class you want to test.

Looks like you want to test your repository. To do that you can use test slice with @DataJpaTest.

Then in your case, you don't need to mock the optional.

In case you want to test a Service class or another class that use your UserRepository, you will define a mock and your class will looks like this :

@Mock
private UserRepository repo;

@InjectMocks
private UserService service;

@Test
public void testUpdateUser() {

    when(repo.findById(anyInt()).get()).thenReturn(aNewInstanceOfUser());

    ...

}

For more reading.

Upvotes: 0

Related Questions