I have a service class which queries the CRUDRepository
based on id, name and money
.
If data exists, it will extract the money, add 100 to it and save the updated object in the repository. If data does not exist, it will create a new object and save it in the repository.
Person.java
@Value
@Builder
public class Person {
private final UUID id;
private final String name;
@With
private final BigDecimal money;
}
Service.Java
private Person updateOrSave(final UUID id, final String name) {
final Optional<Person> existingPerson = myRepo.findByIdAndName(id, name);
if (existingPerson.isPresent()) {
updatedPerson = existingPerson.withMoney(existingPerson.getMoney().add(new BigDecimal(100)));
return myRepo.save(updatedPerson);
} else {
return myRepo.save(Person.builder()
.id(id)
.name(name)
.money(money)
.build()));
}
}
I need to write a unit test for this scenario where data exists.
I am able to write the testcase but the issue is myCrudRepository.save()
returns null
.
So this is how I am testing it.
Test.java
@ExtendWith(MockitoExtension.class)
class PersonTest {
@Mock
private MyRepo myRepo;
@InjectMocks
private Service service;
@Test
void updateExistingMoney() {
final UUID id = UUID.randomUUID();
final String name = "TestName";
final Optional<Person> person = Optional.of(Person.builder()
.id(id)
.name(name)
.money(new BigDecimal(10))
.build());
final Person finalPerson = Person.builder()
.id(id)
.name(name)
.money(new BigDecimal(110))
.build()
when(myRepo.findByIdAndName(id, name))
.thenReturn(person);
service.updateOrSave(id, name);
verify(myRepo).save(finalPerson);
}
Is this correct way of testing or is it wrong ?
CodePudding user response:
You can use the concept of Argument captors to capture the object, which was passed as an argument to the mocked repo.
@ExtendWith(MockitoExtension.class)
class PersonTest {
@Mock
private MyRepo myRepo;
@InjectMocks
private Service service;
@Captor
private ArgumentCaptor<Person> personCaptor;
@Test
void updateExistingMoney() {
final UUID id = UUID.randomUUID();
final String name = "TestName";
final Optional<Person> person = Optional.of(Person.builder()
.id(id)
.name(name)
.money(new BigDecimal(10))
.build());
final Person finalPerson = Person.builder()
.id(id)
.name(name)
.money(new BigDecimal(110))
.build()
when(myRepo.findByIdAndName(id, name))
.thenReturn(person);
service.updateOrSave(id, name);
verify(myRepo).save(personCaptor.capture());
final Person actual = personCaptor.getValue();
// Do checks on expected person vs. the actual one
}