Spring启动+云| Zuul 代理 |集成测试
Spring Boot + Cloud | Zuul Proxy | Integration testing
当使用 Spring Boot 构建微服务时,使用 MockRestServiceServer
.
编写广泛且易读的集成测试和模拟远程服务请求非常容易
有没有办法使用类似的方法对 ZuulProxy
执行额外的集成测试?我想要实现的是能够模拟 ZuulProxy
将转发到的远程服务器并验证我的所有 ZuulFitler
是否按预期运行。但是,ZuulProxy
使用的是 Netflix 的 RestClient
(似乎已弃用?),它自然不会使用 RestTemplate
,它可以由 MockRestServiceServer
重新配置,而我目前可以'找不到模拟远程服务对代理请求的响应的好方法。
我有一个微服务负责处理 API 会话密钥的创建,然后将类似于 API 网关。使用 Zuul Proxy 转发到底层暴露的服务,Zuul Filters 将检测 Session key 是否有效。因此,集成测试将创建一个有效会话,然后转发到一个假端点,例如 'integration/test'.
通过在 @WebIntegrationTest
上设置配置 属性 可以指定 'integration/test' 是一个新的端点,我可以成功地模拟通过 RestTemplate
处理的所有服务但不是 Zuul 转发。
实现转发目标服务模拟的最佳方法是什么?
查看 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")));
}
}
接受的答案有主要思想。但在找出问题之前,我在某些方面苦苦挣扎。所以我想用 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/
同一端口上的本地主机 Wiremock 运行 将无法帮助您。我仍在尝试找到一个类似的集成测试,我可以在其中模拟来自 Spring 的 Bean 并阅读 url
Zuul 代理在发出请求调用之前选择路由的内容。
当使用 Spring Boot 构建微服务时,使用 MockRestServiceServer
.
有没有办法使用类似的方法对 ZuulProxy
执行额外的集成测试?我想要实现的是能够模拟 ZuulProxy
将转发到的远程服务器并验证我的所有 ZuulFitler
是否按预期运行。但是,ZuulProxy
使用的是 Netflix 的 RestClient
(似乎已弃用?),它自然不会使用 RestTemplate
,它可以由 MockRestServiceServer
重新配置,而我目前可以'找不到模拟远程服务对代理请求的响应的好方法。
我有一个微服务负责处理 API 会话密钥的创建,然后将类似于 API 网关。使用 Zuul Proxy 转发到底层暴露的服务,Zuul Filters 将检测 Session key 是否有效。因此,集成测试将创建一个有效会话,然后转发到一个假端点,例如 'integration/test'.
通过在 @WebIntegrationTest
上设置配置 属性 可以指定 'integration/test' 是一个新的端点,我可以成功地模拟通过 RestTemplate
处理的所有服务但不是 Zuul 转发。
实现转发目标服务模拟的最佳方法是什么?
查看 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")));
}
}
接受的答案有主要思想。但在找出问题之前,我在某些方面苦苦挣扎。所以我想用 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/
同一端口上的本地主机 Wiremock 运行 将无法帮助您。我仍在尝试找到一个类似的集成测试,我可以在其中模拟来自 Spring 的 Bean 并阅读 url
Zuul 代理在发出请求调用之前选择路由的内容。