【问题标题】:I want to mock a server before bean creation in spring boot integration test我想在 Spring Boot 集成测试中创建 bean 之前模拟服务器
【发布时间】: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 对编辑后的代码示例感到抱歉。

标签: spring-boot spring-mvc junit integration-testing spring-boot-test


【解决方案1】:

使用@InjectMocks

参考:documentationExplaination 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;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-07
    • 2023-03-31
    • 2015-08-02
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    相关资源
    最近更新 更多