如何为在其中创建对象并将其传递给模拟对象的方法编写单元测试?

How to write a unit test for method that creates an object inside of it and passes it to mocked object?

这是我要测试的方法,certificateRepository 看到一个模拟,QueryFiltersConfig config 是我传递给该模拟方法的对象。我正在使用 JUnit 5 作为测试框架。

@Override
public List<GiftCertificateDto> fetchCertificatesWithFilters(Optional<String> tagName, Optional<List<String>> sortTypes, Optional<String> searchPattern) {
        QueryFiltersConfig.Builder filterConfigBuilder = QueryFiltersConfig.builder();
        tagName.ifPresent(filterConfigBuilder::withTag);
        addSortsToConfig(sortTypes, filterConfigBuilder);
        searchPattern.ifPresent(filterConfigBuilder::withSearchPattern);
        QueryFiltersConfig config = filterConfigBuilder.build();
        return certificateRepository.findWithFilters(config).stream()
                .map(dtoTranslator::giftCertificateToDto).collect(Collectors.toList());
}

在那种情况下,我该如何编写模拟初始化(Mockito.when(...) 语句)?或者我应该反过来做?如果是 - 如何?

使用 ArgumentCaptor 可以捕获传递给方法的参数以便对其进行检查。当您无法访问我们要测试的方法之外的参数时,这尤其有用。 Here is a good reference.

让我尝试根据您的方法举个例子。我假设你有一个名为 YourService 的服务,你可以使用 @InjectMocks 注释来注入模拟的 CertificateRepository.

  1. 然后你使用@Captor类型QueryFiltersConfig的ArgumentCaptor字段来存储我们捕获的参数。

  2. Mockito.verify 使用 ArgumentCaptor 捕获 QueryFiltersConfig 并使用 configCaptor.getValue()

    捕获参数
  3. 使用断言检查捕获的值。

@RunWith(MockitoJUnitRunner.class)
public class CertificateRepositoryTest {
    @Mock
    CertificateRepository certificateRepository;
    @InjectMocks
    YourService yourService;
    // 1
    @Captor
    ArgumentCaptor<QueryFiltersConfig> configCaptor;

    @Test
    public void testWithCaptor() {
        // 2 - call your service and let it do whatever it needs
        // with the parameter passed to it
        yourService.fetchCertificatesWithFilters(parameters);

        // 2 - capture the object created inside your service
        Mockito.verify(certificateRepository)
              .findWithFilters(configCaptor.capture());
        QueryFiltersConfig value = configCaptor.getValue();
        // 3 - and make sure that the value is correct
        assertEquals(expectedValue, value);
    }
}