【问题标题】:Correct way to unit test CrudRepository.save()单元测试 CrudRepository.save() 的正确方法
【发布时间】:2022-01-14 18:40:46
【问题描述】:

我有一个基于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() 返回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 ?

【问题讨论】:

标签: java spring-boot junit crud-repository


【解决方案1】:

您可以使用参数捕获器的概念来捕获作为参数传递给模拟存储库的对象。

@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
    }

【讨论】:

  • 非常感谢您。所以我的测试用例工作正常。我只是不知道如何捕获结果并断言值。感谢所有帮助。
猜你喜欢
  • 2016-03-25
  • 1970-01-01
  • 2015-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-28
  • 1970-01-01
相关资源
最近更新 更多