【发布时间】:2019-12-02 20:16:32
【问题描述】:
我将spring-boot 与WebClient 一起使用,它作为bean 自动装配。
问题:在编写junit集成测试时,我必须使用okhttp MockWebServer。这个模拟总是在一个随机端口上启动,例如localhost:14321。
现在我的WebClient 当然有一个固定的 url,它将请求发送到。此 url 可能由 application.properties 参数(如 webclient.url=https://my.domain.com/)给出,因此我可以在 junit 测试中覆盖该字段。但只是静态的。
问题:如何重置 @SpringBootTest 内的 WebClient bean,以便它始终将请求发送到我的模拟服务器?
@Service
public class WebClientService {
public WebClientService(WebClient.Builder builder, @Value("${webclient.url}" String url) {
this.webClient = builder.baseUrl(url)...build();
}
public Response send() {
return webClient.body().exchange().bodyToMono();
}
}
@Service
public void CallingService {
@Autowired
private WebClientService service;
public void call() {
service.send();
}
}
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MyWebTest {
@Autowired
private CallingService calling;
@Test
public void test() {
MockWebServer mockWebServer = new MockWebServer();
System.out.println("Current mock server url: " + mockWebServer.url("/").toString()); //this is random
mockWebServer.enqueue(new MockResponse()....);
//TODO how to make the mocked server url public to the WebClient?
calling.call();
}
}
如您所见,我正在编写一个完整的真实世界 junit 集成测试。唯一的问题是:如何将MockWebServer url 和端口传递给WebClient,以便它自动将请求发送到我的模拟??
旁注:我绝对需要在MockWebServer 中设置一个随机端口,以免干扰其他正在运行的测试或应用程序。因此必须坚持随机端口,并找到一种方法将其传递给网络客户端(或动态覆盖应用程序属性)。
更新: 我想出了以下内容,这是可行的。但也许有人知道如何使模拟服务器字段非静态?
@ContextConfiguration(initializers = RandomPortInitializer.class)
public abstract class AbstractITest {
@ClassRule
public static final MockWebServer mockWebServer = new MockWebServer();
public static class RandomPortInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(applicationContext,
"webclient.url=" + mockWebServer.url("/").toString());
}
}
}
【问题讨论】:
-
您好!如果要进行集成测试,为什么要使用
MockWebServer?SpringBootTest.WebEnvironment.RANDOM_PORT还不足以创建一个完整的 Web 环境(无需模拟任何东西)吗? -
我需要模拟在我的应用程序中请求的 remote 网络服务器。当然,我不能针对实时远程网络服务器执行测试。所以这是被嘲笑的。正如所写,我正在创建一个 client 应用程序,而不是服务器!
-
@membersound 你试过我的解决方案了吗?
-
如所写,我必须模拟
WebClient从我的应用程序发出的remote 连接。这与 spring 启动我自己的网络服务器的RANDOM_PORT属性无关! -
但是你说你的远程服务器也有随机端口。顺便说一句,你为什么不能尝试一个固定的端口?不管是客户端还是服务端,我认为你可以很容易地找到一个免费且稳定的端口
标签: java spring spring-boot okhttp3 mockwebserver