Home > Blockchain >  How to write a unit test for method that creates an object inside of it and passes it to mocked obje
How to write a unit test for method that creates an object inside of it and passes it to mocked obje

Time:10-17

Here is the method I want to test with certificateRepository seeing a mock and QueryFiltersConfig config being the object that I pass to that mock's method. I am using JUnit 5 as test framework.

@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());
}

How can I write the mock initialization (Mockito.when(...) statements) in that case? Or maybe I should do it the other way around? If so – how?

CodePudding user response:

Use the ArgumentCaptor that allows you to capture an argument passed to a method in order to inspect it. This is especially useful when you can't access the argument outside of the method we'd like to test. Here is a good reference.

Let me try to give an example based on your method. I am assuming you have a service called YourService which you can use @InjectMocks annotation to inject the mocked CertificateRepository.

  1. Then you use the @Captor ArgumentCaptor field of type QueryFiltersConfig to store our captured argument.

  2. Mockito.verify with the ArgumentCaptor to capture the QueryFiltersConfig and capture the argument using configCaptor.getValue()

  3. Inspect the Captured Value using an assert.

@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);
    }
}
  • Related