ArgumentCaptor在单元测试中的使用

2022-06-13 00:00:00 testing unit-testing java junit junit5

我正在尝试为以下服务方法创建单元测试:

public CompanyDTO update(CompanyRequest companyRequest, UUID uuid) {

    final Company company = companyRepository.findByUuid(uuid)
            .orElseThrow(() -> new EntityNotFoundException("Not found"));            
    
    company.setName(companyRequest.getName());

    final Company saved = companyRepository.save(company);
    return new CompanyDTO(saved);
}

我创建了以下单元测试:

@InjectMocks
private CompanyServiceImpl companyService;

@Mock
private CompanyRepository companyRepository;

@Captor
ArgumentCaptor<Company> captor;



@Test
public void testUpdate() {
    final Company company = new Company();
    company.setName("Company Name");

    final UUID uuid = UUID.randomUUID();
    final CompanyRequest request = new CompanyRequest();
    request.setName("Updated Company Name");
  
    when(companyRepository.findByUuid(uuid))
        .thenReturn(Optional.ofNullable(company));        
    when(companyRepository.save(company)).thenReturn(company);

    CompanyDTO result = companyService.update(request, uuid);

    /* here we get the "company" parameter value that we send to save method 
    in the service. However, the name value of this paremeter is already 
    changed before passing to save method. So, how can I check if the old 
    and updated name value? */
    Mockito.verify(companyRepository).save(captor.capture());

    Company savedCompany = captor.getValue();

    assertEquals(request.getName(), savedCompany.getName());
}

据我所知,我们使用ArgumentCaptor来捕获我们传递给方法的值。在本例中,我需要在正确的时间捕捉值,并比较发送到更新方法的名称的更新值和更新后的名称属性的返回值。然而,我找不到如何正确地测试它,并在我的测试方法中添加必要的注释。那么,我应该如何使用ArgumentCaptor来验证我的UPDATE方法使用给定值(&QOOT;UPDATED Company NAME&QOOT;)更新公司。


解决方案

以下是您的ArgumentCaptor方案。

测试中的代码:

public void createProduct(String id) {
  Product product = new Product(id);
  repository.save(product);
}
请注意,a)我们在测试的代码中创建了一个对象,b)我们想要验证该对象的特定内容,c)我们在调用之后无法访问该对象。这些情况几乎就是你需要捕获者的地方。

您可以这样测试它:

void testCreate() {
  final String id = "id";
  ArgumentCaptor<Product> captor = ArgumentCaptor.for(Product.class);

  sut.createProduct(id);

  // verify a product was saved and capture it
  verify(repository).save(captor.capture());
  final Product created = captor.getValue();

  // verify that the saved product which was captured was created correctly
  assertThat(created.getId(), is(id));
}

相关文章