我想在 Spring Boot 集成测试中创建 bean 之前模拟服务器
Posted
技术标签:
【中文标题】我想在 Spring Boot 集成测试中创建 bean 之前模拟服务器【英文标题】:I want to mock a server before bean creation in spring boot integration test 【发布时间】:2020-01-15 02:24:06 【问题描述】:我正在 spring-boot 中编写集成测试。 我的 bean 之一是使用 UrlResource("http://localhost:8081/test") 进行创建。 我想创建一个模拟服务器,它将为上述 url 提供模拟响应。 但我希望在初始化任何 bean 之前创建这个模拟服务器,因为模拟服务器应该可以在 bean 初始化之前为请求提供服务。
我尝试在 @TestConfiguration 中使用 MockRestServiceServer
以下是失败的伪代码:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TestApiGatewayApplicationTests
@Autowired
private TestRestTemplate restTemplate;
@Test
public void contextLoads()
@TestConfiguration
class TestConfig
@Bean
public RestTemplateBuilder restTemplateBuilder()
RestTemplate restTemplate = new RestTemplate();
MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);
String mockKeyResponse = "\"a\":\"abcd\"";
mockServer.expect(requestTo("http://localhost:8081/test"))
.andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(mockKeyResponse, MediaType.TEXT_PLAIN));
RestTemplateBuilder builder = mock(RestTemplateBuilder.class);
when(builder.build()).thenReturn(restTemplate);
return builder;
以下是创建要测试的bean的示例代码。
@Configuration
public class BeanConfig
@Bean
public SampleBean sampleBean()
Resource resource = new UrlResource("");
// Some operation using resource and create the sampleBean bean
return sampleBean;
使用上述方法我得到 “ java.net.ConnectException:连接被拒绝(连接被拒绝)” 错误,因为它无法访问http://localhost:8081/test 端点。
【问题讨论】:
你正在这里构建一个新的模拟,而不是返回你构建的模拟return mock(RestTemplateBuilder.class).build();
看起来很时髦。
@ThomasAndolf 对编辑后的代码示例感到抱歉。
【参考方案1】:
使用@InjectMocks
。
参考:documentation 和 Explaination with example.
【讨论】:
无法使用 @InjectMocks。我必须在 bean 初始化开始之前或在调用特定 bean 之前创建对象并准备好 url。【参考方案2】:我通过在 testConfiguration 中创建一个 MockServiceServer 解决了这个问题。 示例代码如下。
@TestConfiguration
static class TestConfig
@Bean
public RestTemplateBuilder restTemplateBuilder()
RestTemplate restTemplate = new RestTemplate();
MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);
String mockKeyResponse = "\"a\":\"abcd\"";
mockServer.expect(requestTo("http://localhost:8081/test"))
.andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(mockKeyResponse, MediaType.TEXT_PLAIN));
RestTemplateBuilder builder = mock(RestTemplateBuilder.class);
when(builder.build()).thenReturn(restTemplate);
return builder;
然后在我需要使用它的类 BeanConfig 中,我使用构造函数注入自动装配,以便在创建 BeanConfig 类的 bean 之前创建 RestTemplate。 以下是我的做法。
@Configuration
public class BeanConfig
private RestTemplate restTemplate;
public BeanConfig(RestTemplate restTemplate)
this.restTemplate = restTemplate;
@Bean
public SampleBean sampleBean()
Resource resource = new UrlResource("");
// Some operation using resource and create the sampleBean bean
return sampleBean;
【讨论】:
以上是关于我想在 Spring Boot 集成测试中创建 bean 之前模拟服务器的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Boot 中创建一个调用包含构造函数注入的服务的测试?
如何在 Spring Boot 客户端应用程序中创建不共享底层网络连接的套接字
用于集成测试的 Spring Boot @LocalServerPort 的 DotNet 替代方案
如何在 Spring Boot 中创建不同的 ThreadPoolTaskExecutor? [复制]