问题描述
我正在将spring-boot
与WebClient
一起使用,并且将其自动装配为bean.
I'm using spring-boot
with WebClient
, which is autowired as a bean.
问题:编写junit
集成测试时,我必须使用okhttp MockWebServer
.该模拟总是在随机端口(例如localhost:14321
)上启动.
Problem: when writing a junit
integration test, I have to use okhttp MockWebServer
. This mock always starts up on a random port, eg localhost:14321
.
现在我的WebClient
当然有一个固定的URL,它将请求发送到该URL.该网址可能由application.properties
参数(例如webclient.url=https://my.domain.com/
)给出,因此我可以在junit
测试中覆盖该字段.但是只是静态的.
Now my WebClient
of course has a fixed url that it sends the requests to. This url may be given by an application.properties
parameter like webclient.url=https://my.domain.com/
, so I could override that field in a junit
test. But only statically.
问题:如何重置@SpringBootTest
中的WebClient
bean,以便它始终将请求发送到我的模拟服务器?
Question: how can I reset the WebClient
bean inside a @SpringBootTest
so that it sends the requests always to my mock server?
@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
网址和端口传递给WebClient
,以便它自动将请求发送到我的模拟计算机?
As you see, I'm writing a full realworld junit integration test. The only problem is: how can I pass the MockWebServer
url and port to the WebClient
so that it automatically sends the requests to my mock??
旁注:我肯定在这里MockWebServer
中需要一个随机端口,以免干扰其他正在运行的测试或应用程序.因此,必须坚持使用随机端口,并找到一种方法将其传递给webclient(或动态覆盖应用程序属性).
Sidenote: I definitely need a random port in MockWebServer
here to not interfer with other running tests or applications. Thus have to stick to the random port, and find a way to pass it to the webclient (or dynamically override the application property).
更新:我想出了以下可行的方法.但是也许有人知道如何使模拟服务器字段非静态?
Update:I came up with the following, which works. But maybe anyone knows how to make the mockserver field non-static?
@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());
}
}
}
推荐答案
您可以使用setField(Object targetObject, String name, Object value) /org/springframework/test/util/ReflectionTestUtils.html"rel =" nofollow noreferrer> ReflectionTestUtils .
You can use the method setField(Object targetObject, String name, Object value)
from ReflectionTestUtils.
@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()....);
WebClientService newWebClientService = new WebClientService(WebClient.builder(), mockWebServer.url("/").toString());
ReflectionTestUtils.setField(calling, "service", newWebClientService);
calling.call();
}
这篇关于如何在JUnit测试中将MockWebServer端口设置为WebClient?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!