mockito 如何模拟helidon mp项目中的web客户端调用单元测试

cyvaqqii  于 2023-06-29  发布在  其他
关注(0)|答案(1)|浏览(180)

有没有一种方法可以模拟从服务到单元测试的Web客户端调用?示例调用:下面的片段用于使用webclient从helidon应用程序调用consul服务。它可以是对外部服务的任何类型的Web客户端调用。
WebClientResponse webClientResponse = webClient.put().path(sessionRenewPath).submit().get();
我期望模拟这个webclient调用并获得webClientResponse。如何构建一个mock webClientResponse?
我正在尝试这方面的东西,但失败了

@Mock
WebClientRequestBuilder webClientRequestBuilder;
@Mock
Single<WebClientResponse> webClientResponseSingle;
@Mock
WebClientResponse webClientResponse;

Mockito.when(webClient.post()).thenReturn(webClientRequestBuilder);
        Mockito.doReturn(webClientRequestBuilder).when(webClientRequestBuilder).path(Mockito.any(String.class));
        Mockito.doReturn(webClientResponseSingle).when(webClientRequestBuilder).submit();
        Mockito.doReturn(webClientResponse).when(webClientResponseSingle).get();

qq24tv8q

qq24tv8q1#

虽然您可以使用Mockito模拟第三方服务响应,但更好的解决方案是使用Hoverfly等专用库在HTTP层模拟第三方API。与Mockito相比,Hoverfly的最大优点是,您的代码不会被所有可能不稳定且难以长期维护以匹配第三方API中的更改的模拟实现所覆盖。
你可能会认为Hoverfly是一个caching proxy layer between your service and the 3rd party。代理可以让流量通过到达目的地(如果您希望的话),或者通过从其内部缓存中提供保存的响应来缩短出站呼叫(这是默认行为,也是应该如何使用的)。您的webclient或http客户端代码永远不会知道其中的区别,并且始终像在网络上交谈一样工作。除了项目中测试范围内的maven依赖项之外,您不需要任何额外的基础设施设置来完成所有这些工作。
你将获得的额外好处是(这是Mockito永远无法比拟的)
1.用真实、可重用的模拟替换缓慢、不稳定的API依赖。
1.模拟网络延迟、随机故障或速率限制,以测试边缘情况。
1.无缝地模拟来自unitest代码的出站调用的API响应以及来自被测应用程序内部的出站调用(可以无差别地模拟来自观察端口上的JVM的所有出站调用的响应)。
1.导出、共享、编辑和导入API模拟
1.通过CLI或代码捕获API响应并签入响应,作为CI管道自动化的黄金参考。
1.通过重新捕获响应并更新存储库中的黄金参考,将更改与第三方API响应相匹配,而无需更改任何测试自动化代码。
您可以通过注解以声明方式向JUnit测试类添加hoverfly支持,如下所示:

@HelidonTest // HelidonTest is Optional if you want CDI in tests!
    @HoverflySimulate(
        source = @HoverflySimulate.Source(value = "<path-to-hoverfly-saved-api-response>.json", type = HoverflySimulate.SourceType.DEFAULT_PATH),
        config = @HoverflyConfig(proxyLocalHost = true, proxyPort = <API-PORT>, webServer = true, disableTlsVerification = true)
    )
    @ExtendWith(HoverflyExtension.class)
    class TestRemoteServiceWithHoverfly 
    {
        @Test
        public void testWebClientToRemoteService()
        { 
           Response remoteResponse = 
 _target.path(<API_PATH>).request().get()
        }

        @Inject
        private WebTarget _target;
    }

相关问题