我使用的是spring-boot
和WebClient
,这是一个自动的豆子。
问题:在编写junit
集成测试时,我必须使用okhttp MockWebServer
。这个模拟总是在随机端口上启动(如localhost:14321
)。
现在,我的WebClient
当然有了一个固定的url,它将请求发送给它。这个url可能由application.properties
参数(如webclient.url=https://my.domain.com/
)提供,因此我可以在junit
测试中重写该字段。但只是静态的。
问题:我如何在一个WebClient
内重置@SpringBootTest
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();
}
}
正如您所看到的,我正在编写一个完整的realworld junit集成测试。唯一的问题是:如何将MockWebServer
url和端口传递给WebClient
,以便它自动将请求发送到模拟??
Sidenote:我肯定需要MockWebServer
中的一个随机端口,以避免与其他正在运行的测试或应用程序交互。因此,必须坚持使用随机端口,并找到一种将其传递给webclient (或动态覆盖应用程序属性)的方法。
更新:我想出了以下内容,这是可行的。但是,也许有人知道如何使mockserver字段是非静态的。
@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());
}
}
}
发布于 2020-10-07 09:42:55
由于SpringFramework5.2.5(SpringBoot2.x),您可以使用DynamicPropertySource
注释,这非常方便。
下面是一个完整的示例,您可以使用它与MockWebServer
绑定正确的端口:
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public abstract class AbstractIT {
static MockWebServer mockWebServer;
@DynamicPropertySource
static void properties(DynamicPropertyRegistry r) throws IOException {
r.add("some-service.url", () -> "http://localhost:" + mockWebServer.getPort());
}
@BeforeAll
static void beforeAll() throws IOException {
mockWebServer = new MockWebServer();
mockWebServer.start();
}
@AfterAll
static void afterAll() throws IOException {
mockWebServer.shutdown();
}
}
https://stackoverflow.com/questions/57186938
复制相似问题