如何使用 mockito 在服务测试中模拟工厂方法

How to mock factory method in service test with mockito

您好,我正在尝试测试服务层。我已经为 ConverterFactory 编写了测试。我想我需要 ConverterServiceImpl 使用的模拟依赖项 classes 但我仍然得到 NullPointerException

这是我的服务class

@Service
@RequiredArgsConstructor
public class ConverterServiceImpl implements ConverterService {

    ConverterFactory factory = new ConverterFactory();
    private final WebLinkRepository webLinkRepository;
    private final DeepLinkRepository deepLinkRepository;

    @Override
    public DeepLinkResponse toDeepLink(WebLinkRequest webLinkRequest) {

        WebLink webLink;
        String url = webLinkRequest.getUrl();
        Converter converter = factory.getConverter(url);


        webLink = new WebLink();
        webLink.setUrl(url);
        String convertedUrl = converter.toDeepLink(url);
        webLink.setConvertedUrl(convertedUrl);
        webLinkRepository.save(webLink);

        return new DeepLinkResponse(convertedUrl);
    }
}

这是测试

@RunWith(MockitoJUnitRunner.class)
public class ConverterServiceImplTest {


    @InjectMocks
    ConverterServiceImpl converterService;

    @Mock
    WebLinkRepository webLinkRepository;

    @Mock
    DeepLinkRepository deepLinkRepository;

    @Mock
    ConverterFactory converterFactory;

    @Mock
    ProductConverter productConverter;

    @Mock
    WebLinkRequest webLinkRequest;

    @BeforeAll
    void init(){
        webLinkRequest.setUrl(WEBLINK_ONLY_PRODUCT);
    }

    @Test
    public void toDeepLink_only_content_id() {
        ConverterFactory converterFactory = mock(ConverterFactory.class);
        when(converterFactory.getConverter(any())).thenReturn(productConverter);

        DeepLinkResponse deepLinkResponse = converterService.toDeepLink(webLinkRequest);
        assertEquals(deepLinkResponse.getUrl(),"ty://?Page=Product&ContentId=1925865");

    }
}

这段代码抛出错误说。我在这里做错了什么?:

java.lang.NullPointerException
    at com.example.converter.service.factory.ConverterFactory.getConverter(ConverterFactory.java:13)

您不需要在测试方法中再次创建 ConverterFactory converterFactory = mock(ConverterFactory.class),因为您已经创建了 class 字段等模拟。

此外,您没有将测试方法中创建的 mock 注入到被测 class 中,而创建为字段的 mock 是使用 @InjectMocks 注解注入的。

所以只需从测试方法中删除 ConverterFactory converterFactory = mock(ConverterFactory.class):

@RunWith(MockitoJUnitRunner.class)
public class ConverterServiceImplTest {


    @InjectMocks
    ConverterServiceImpl converterService;

    @Mock
    ConverterFactory converterFactory;

    // other stuff


    @Test
    public void toDeepLink_only_content_id() {
        when(converterFactory.getConverter(any())).thenReturn(productConverter);

        // other stuff

        converterService.toDeepLink(webLinkRequest);
    }
}