单元测试的正确方法 CrudRepository.save()
Correct way to unit test CrudRepository.save()
我有一项服务 class,它根据 id, name and money
.
查询 CRUDRepository
如果数据存在,它将提取钱,向其添加 100 并将更新后的对象保存在存储库中。
如果数据不存在,它将创建一个新对象并将其保存在存储库中。
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()));
}
}
我需要为这种存在数据的场景编写单元测试。
我能够编写测试用例,但问题是 myCrudRepository.save()
returns null
.
这就是我测试它的方式。
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 ?
您可以使用 Argument captors 的概念来捕获作为参数传递给模拟存储库的对象。
@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
}
我有一项服务 class,它根据 id, name and money
.
CRUDRepository
如果数据存在,它将提取钱,向其添加 100 并将更新后的对象保存在存储库中。 如果数据不存在,它将创建一个新对象并将其保存在存储库中。
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()));
}
}
我需要为这种存在数据的场景编写单元测试。
我能够编写测试用例,但问题是 myCrudRepository.save()
returns null
.
这就是我测试它的方式。
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 ?
您可以使用 Argument captors 的概念来捕获作为参数传递给模拟存储库的对象。
@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
}