[英]How to set urls with port of StubRunner from spring-cloud-contract in spring-cloud-gateway contract tests
我有一个 spring 云网关应用程序,它将请求路由到另一个服务。 另一个服务定义了在测试中由 spring 云网关应用程序作为存根导入的合约。
现在我想在我的网关中进行合同测试,这将消耗另一个服务的存根。 问题是我不知道如何将StubRunnerPort
作为属性/环境注入,因此可以通过我的配置 class 选择它并相应地配置路由:
Api网关路由配置
@Configuration
class GatewayConfig {
@Value("${subscriptions.url}")
private String subscriptionsUrl;
@Autowired
private TokenRelayGatewayFilterFactory tokenFilterFactory;
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http.csrf(ServerHttpSecurity.CsrfSpec::disable);
return http.build();
}
@Bean
RouteLocator routeLocator(final RouteLocatorBuilder routeLocatorBuilder) {
return routeLocatorBuilder.routes()
.route("subscriptions", subscriptionsRoute())
.build();
}
private Function<PredicateSpec, Buildable<Route>> subscriptionsRoute() {
return spec -> spec
.path("/subscriptions/**")
.filters(s -> s.filter(tokenFilterFactory.apply()).prefixPath("/v1"))
.uri(subscriptionsUrl);
}
}
以及测试 class:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {PnApiGatewayApp.class})
@AutoConfigureStubRunner(ids = "io.mkrzywanski:subscription-app:+:stubs", stubsMode = StubRunnerProperties.StubsMode.CLASSPATH)
@ActiveProfiles("test")
class SubscriptionSpec {
private WebTestClient webClient;
@LocalServerPort
private int port;
@StubRunnerPort("io.mkrzywanski:subscription-app")
private int stubRunnerPort;
@Autowired
ConfigurableEnvironment environment;
@BeforeEach
void setup() {
String baseUri = "http://localhost:" + port;
this.webClient = WebTestClient.bindToServer()
.responseTimeout(Duration.ofSeconds(10))
.baseUrl(baseUri).build();
}
@Test
void test() {
String body = "{\"userId\":\"22e90bbd-7399-468a-9b76-cf050ff16c63\",\"itemSet\":[{\"value\":\" Rainbow Six\"}]}";
var response = webClient.post()
.uri("/subscriptions")
.header("Authorization", "Bearer xxx")
.header("Content-type", MediaType.APPLICATION_JSON_VALUE)
.bodyValue(body)
.exchange()
.expectStatus().isCreated()
.expectBody(String.class)
.value(Matchers.equalTo("{\"subscriptionId : \"6d692849-58fd-439b-bb2c-50a5d3669fa9\"\"}"));
}
理想情况下,我想要subscriptions.url
。url 属性设置在配置存根运行器之后但在Spring 选择我的网关配置之前,这样 url 将工作。
我已经尝试过使用ApplicationContextInitializer
但在启动初始化程序实例时似乎尚未配置 StubRunnerPort 。
所以问题是 - 如何获取存根运行器端口并使用它将其注入其他服务 url,以便网关将请求路由到测试中的存根运行器?
我通过创建一个测试配置使其工作,该配置扩展了包含 url 属性和RouteLocator
配置的配置,并且依赖于batchStubRunner
bean:
@DependsOn("batchStubRunner")
@EnableAutoConfiguration
@Import(LoggingFilter.class)
class GatewayTestConfig extends GatewayConfig implements InitializingBean {
@Autowired
ConfigurableEnvironment environment;
@Override
public void afterPropertiesSet() {
this.subscriptionsUrl = "http://localhost:" + environment.getProperty("stubrunner.runningstubs.io.mkrzywanski.subscription-app.port");
}
}
这里的关键点是:
batchStubRunner
bean 可用后才运行配置,因此可以在environment
中找到 StrubRunner 的端口InitializingBean
,因此我能够覆盖现在在父配置中protected
的subscriptionsUrl
subscriptionsUrl
被覆盖之后——它可以用来从父配置中配置RouteLocator
bean。测试现在看起来像这样:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {GatewayTestConfig.class})
@AutoConfigureStubRunner(ids = "io.mkrzywanski:subscription-app:+:stubs", stubsMode = StubRunnerProperties.StubsMode.CLASSPATH)
@ActiveProfiles("test")
class SubscriptionSpec {
private WebTestClient webClient;
@LocalServerPort
private int port;
@BeforeEach
void setup() {
String baseUri = "http://localhost:" + port;
this.webClient = WebTestClient.bindToServer()
.responseTimeout(Duration.ofSeconds(10))
.baseUrl(baseUri).build();
}
@Test
void shouldRouteToSubscriptions() {
String body = "{\"userId\":\"22e90bbd-7399-468a-9b76-cf050ff16c63\",\"itemSet\":[{\"value\":\"Rainbow Six\"}]}";
webClient.post()
.uri("/subscriptions")
.header("Accept", MediaType.APPLICATION_JSON_VALUE)
.header("Authorization", "Bearer xxx")
.header("Content-type", MediaType.APPLICATION_JSON_VALUE)
.bodyValue(body)
.exchange()
.expectStatus().isCreated()
.expectBody()
.jsonPath("$.subscriptionId").exists()
.jsonPath("$.subscriptionId").value(IsUUID.UUID());
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.