【问题标题】:Spring Boot + Cloud | Zuul Proxy | Integration testingSpring Boot + 云 | Zuul 代理 |集成测试
【发布时间】:2016-04-13 03:45:22
【问题描述】:

当使用 Spring Boot 构建微服务时,它非常容易编写广泛且可读性强的集成测试,并使用 MockRestServiceServer 模拟远程服务请求。

有没有办法使用类似的方法对ZuulProxy 执行额外的集成测试?我想要实现的是能够模拟ZuulProxy 将转发到的远程服务器,并验证我所有的ZuulFitlers 的行为是否符合预期。但是,ZuulProxy 正在使用来自 Netflix 的 RestClient(似乎已弃用?),它自然不使用 RestTemplate 可以由 MockRestServiceServer 重新配置,我目前找不到模拟响应的好方法来自远程服务的代理请求。

我有一个微服务负责处理 API 会话密钥的创建,然后将类似于 API 网关。使用 Zuul Proxy 转发到底层暴露的服务,Zuul Filters 会检测 Session key 是否有效。因此,集成测试会创建一个有效的会话,然后转发到一个假端点,例如“集成/测试”。

可以通过在@WebIntegrationTest 上设置配置属性来指定“集成/测试”是一个新端点,我可以成功模拟所有通过RestTemplate 处理但不是Zuul 转发的服务。

实现模拟前向目标服务的最佳方法是什么?

【问题讨论】:

    标签: java spring-boot integration-testing spring-cloud netflix-zuul


    【解决方案1】:

    查看WireMock。我一直在使用它对我的 Spring Cloud Zuul 项目进行集成级别测试。

    import static com.github.tomakehurst.wiremock.client.WireMock.*;
    
    public class TestClass {
        @Rule
        public WireMockRule serviceA = new WireMockRule(WireMockConfiguration.options().dynamicPort());
    
        @Before
        public void before() {
            serviceA.stubFor(get(urlPathEqualTo("/test-path/test")).willReturn(aResponse()
                .withHeader("Content-Type", "application/json").withStatus(200).withBody("serviceA:test-path")));
        }
    
        @Test
        public void testRoute() {
            ResponseEntity<String> responseEntity = this.restTemplate.getForEntity("/test-path/test", String.class);
            assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
    
            serviceA.verify(1, getRequestedFor(urlPathEqualTo("/test-path/test")));
        }
    }
    

    【讨论】:

    • 是否需要添加任何配置才能使其正常工作?我正在尝试做类似的事情,但 Zuul 没有选择路线。我得到了这个异常Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: strategie。我想这来自 Zuul 配置,期望来自服务发现服务器(在本例中为 Eureka)的信息,以将调用路由到正确的 ip。
    【解决方案2】:

    接受的答案具有主要思想。但我在某些方面挣扎,直到找出问题所在。所以我想用 Wiremock 来展示一个更完整的答案。

    测试:

    @ActiveProfiles("test")
    @TestPropertySource(locations = "classpath:/application-test.yml")
    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    @AutoConfigureWireMock(port = 5001)
    public class ZuulRoutesTest {
    
        @LocalServerPort
        private int port;
    
        private TestRestTemplate restTemplate = new TestRestTemplate();
    
        @Before
        public void before() {
    
            stubFor(get(urlPathEqualTo("/1/orders/")).willReturn(aResponse()
                    .withHeader("Content-Type", MediaType.TEXT_HTML_VALUE)
                    .withStatus(HttpStatus.OK.value())));
        }
    
        @Test
        public void urlOrders() {
            ResponseEntity<String> result = this.restTemplate.getForEntity("http://localhost:"+this.port +"/api/orders/", String.class);
            assertEquals(HttpStatus.OK, result.getStatusCode());
    
            verify(1, getRequestedFor(urlPathMatching("/1/.*")));
        }
    }
    

    还有application-test.yml

    zuul:
      prefix: /api
      routes:
        orders:
          url: http://localhost:5001/1/
        cards:
          url: http://localhost:5001/2/
    

    这应该可行。

    但是 Wiremock 对我有一些限制。如果您在不同端口上运行具有不同主机名的代理请求,如下所示:

    zuul:
      prefix: /api
      routes:
        orders:
          url: http://lp-order-service:5001/
        cards:
          url: http://lp-card-service:5002/
    

    在同一端口上运行的 localhost Wiremock 将无法为您提供帮助。我仍在尝试找到一个类似的集成测试,我可以在其中模拟来自 Spring 的 Bean,并阅读 Zuul 代理在发出请求调用之前选择的 url 路由。

    【讨论】:

    • 我认为配置系统的整个想法是能够为“生产”配置设置覆盖,并在测试期间将其指向 localhost 模拟而不是不同的域。否则,您正在研究更多的端到端测试。因此,我不会说这是 Wiremock 的限制,而是可能需要不同方法的设置?例如,您可能希望对模拟服务器的集成测试使用不同的配置文件
    • @Dherik 不是您要找的吗?只需定义两个WireMockRules 并将它们分别存根wiremock.org/docs/junit-rule
    • @Dherik 你应该能够通过使用 url 作为 forward://service-test-A 来解决这个限制,只是为了在 application-test.yml 中进行测试
    猜你喜欢
    • 2015-05-23
    • 2015-11-28
    • 1970-01-01
    • 2020-02-25
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 2020-04-24
    • 2017-10-27
    相关资源
    最近更新 更多