How to Mock JPA Repository'S Save Method in Unit Tests

@Mock jpaRepository calls real save method in other hand @MockBean calls mocked method

@MockBean is a Spring annotation and is the one that should be used in integration tests in order to replace real bean with a mocked one:

Annotation that can be used to add mocks to a Spring
ApplicationContext.

Mockitos @Mock creates a mock of that repository but does not inject that to the BasketService.

If you really need to used the Mockitos mocked version you would have to do it manually in the test:

@Mock
private BasketRepository basketRepo;

@Test
public void createBasketWithSameOrderRef() throws Exception
{
basketService.setBasketRepository(basketRepo);
...

I wrote an article on Mockito Stubbing if you need a further read.

How to mock a JPA Repository to use it for test with Junit?

As you are using Junit5, make sure you have either of these in your code to initialize the mocks:

@ExtendWith(MockitoExtension.class) on the test class

or

@BeforeEach
void beforeEachTest() {
MockitoAnnotations.initMocks(this);
rem = new Rem();
}

Also, you need to make sure that you have injected your mock manually or by using the @InjectMocks annotation into the SUT.

And finally, make sure you do all the mock set-up before calling the actual SUT method.

JPARepository save methods returns null?

PatientModel is passed as parameter to the method and it is converted into PatientEntity patientEntity object. As its a unit test and the PatientRepository has been mocked, so when something is mocked you need to return the value of the mock.

So value should be returned for the statement

PatientEntity savedPatient = repository.save(patientEntity);

You can write the test case in this way

void whenCreatePatientByService_thenPatientRepositoryIsNotEmpty() {
PatientModel patientModel = new PatientModel(134, "Pawel", "Nowak",
"pawel@test.pl", "123456789");
PatientEntity patientEntity = new PatientEntity();
patientEntity.setXxxx("Nowak"); // Other values as per getter and setters

doReturn(patientEntity).when(patientRepository).save(Matchers.any());

PatientModel response = serviceUnderTests.create(patientModel);

assertNotNull(response);
asserEquals("Nowak", response.getXxxxx()); //Getter method name here
}

How to mock a repository method no matter the parameters with mockito

You can use Mockito ArgumentMatchers to match any argument.

when(calculusResultRepository.saveAll(Mockito.any(List.class)))
.thenReturn(resList2);

Unable to mock Spring-Data-JPA repositories with Mockito

There are a few issues here. I assume that you're trying to verify if PersonRepository is mocked or not. However, in your test you wrote:

assertThat(mockingDetails(personService).isMock(), is(true));

You're not mocking PersonService so it makes sense that it would fail this assertion.


Another issue is that Spring Data JPA will also create a bean called personRepository. So your mocked repository bean will be ignored unless you change its name:

@Bean
@Profile("mock-person-repository")
// Change method name to change bean name
public PersonRepository personRepositoryMock() {
logger.info("Mocking: {}", PersonRepository.class);
return mock(PersonRepository.class);
}

But if you do that, then there will be two beans of the type PersonRepository, so autowiring it into your service will fail. To fix that you would have to prevent it from creating the repositories with Spring Data JPA.


Anyhow, a much cleaner solution would be to use MockitoJUnitRunner in stead of Springs test runner. All you would have to do is annotate the class you want to test with @InjectMocks and all dependencies you want to mock and inject with @Mock: like this:

@InjectMocks
private PersonService personService;
@Mock
private SomeBean someBean;
@Mock
private PersonRepository repository;

And then you can delete TestConfig and remove all annotations on your test and replace them with @RunWith(MockitoJUnitRunner.class).



Related Topics



Leave a reply



Submit