如何为在其中创建对象并将其传递给模拟对象的方法编写单元测试?
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
.
然后你使用@Captor
类型QueryFiltersConfig
的ArgumentCaptor字段来存储我们捕获的参数。
Mockito.verify
使用 ArgumentCaptor 捕获 QueryFiltersConfig
并使用 configCaptor.getValue()
捕获参数
使用断言检查捕获的值。
@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);
}
}
这是我要测试的方法,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
.
然后你使用
@Captor
类型QueryFiltersConfig
的ArgumentCaptor字段来存储我们捕获的参数。
捕获参数Mockito.verify
使用 ArgumentCaptor 捕获QueryFiltersConfig
并使用configCaptor.getValue()
使用断言检查捕获的值。
@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);
}
}