【问题标题】:spring boot Dao testspring boot 道测试
【发布时间】:2018-06-10 20:44:21
【问题描述】:

我有一个 dao 实现的测试用例。
测试类代码 -

@RunWith(SpringRunner.class)
@RestClientTest({XyzDaoImpl.class})
@TestPropertySource(locations = "classpath:application-test.properties")
public class XyzDaoTest {

    @Autowired
    XyzDaoImpl xyzDaoImpl;

    @Test
    public void testGetXyzDetails(){
        assertThat(xyzDaoImpl.getXyzDetails("123", null)).isNotNull();
    }
}

xyzDaoImpl.getXyzDetails 方法实现使用 RestTemplate 调用后端。
当我的配置类代码包含 -

时,此测试工作正常
@Bean
public RestTemplate restTemplate() {
    return new RestTemplate();
}

但如果我使用构建器创建其余模板来设置超时等,测试失败 -

@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder
            .setConnectTimeout(timeout)
            .build();
}

尝试使用 @Profile("test") 默认和 @Profile("!test") - 自定义设置创建 Bean,但测试仍然失败。
错误是 -

 testException = java.lang.AssertionError: No further requests expected: HTTP POST http://... url.

【问题讨论】:

    标签: spring testing spring-boot junit


    【解决方案1】:

    使用@RestClientTest 运行时,从RestTemplateBuilder 返回的RestTemplate 不是真正的客户端。它们连接到一个假服务器 (MockRestServiceServer),需要使用预期的请求及其相应的响应进行设置。

    之前使用new RestTemplate() 进行的测试是与网络对话的实际客户端。

    如果你想让RestTemplateBuilder 生成一个RestTemplate 与真实服务器对话,你可以去掉@RestClientTest

    如果你想让RestTemplateBuilder 生成一个模拟的RestTemplateMockRestServiceServer 对话,

    • 使用@RestClientTest
    • 设置MockRestServiceServer
    • 使用RestTemplateBuilder生成RestTemplate,发送上一步配置的请求。

    如下:

    @RunWith(SpringRunner.class)
    @RestClientTest({XyzDaoImpl.class})
    @TestPropertySource(locations = "classpath:application-test.properties")
    public class XyzDaoTest {
        @Autowired
        private MockRestServiceServer server;
    
        @Before
        public void setUp() throws Exception {             
                this.server.expect(requestTo("/...url"))
                  .andRespond(withSuccess("{\"status\": \"ok\"}", MediaType.APPLICATION_JSON));
        }
    
        @Test
        public void testGetXyzDetails(){
            assertThat(xyzDaoImpl.getXyzDetails("123", null)).isNotNull();
        }
    }
    
    class XYZDaoImpl {
        @Autowired
        RestTemplate client;
        String getXyzDetails(String a, String b) {
            return client.getForObject("/...url", String.class);
        }
    }   
    

    【讨论】:

    • 删除 @RestClientTest 解决了这个问题。谢谢
    • 当我像上面一样保持@RunClientTest 进行单元测试时,我无法加载 applicationContext 错误。
      我所做的更改是在设置方法中添加以下内容
      server = MockRestServiceServer.createServer(new RestTemplate());
      还尝试包括在 XYZDaoImpl 中自动生成的类。添加 EnabledWebMvc 后,我没有得到 bean java.servlet.ServletContext
    • ServletContext 由@WebAppConfiguration 提供。它试图找到一个,因为您的组件扫描路径中有一个带有 @EnableWebMvc 的组件。您可以使用@EnableWebMvc 排除组件,也可以添加另一个具有@WebAppConfiguration 的组件。
    猜你喜欢
    • 2019-03-13
    • 2016-10-29
    • 2020-07-21
    • 2021-10-19
    • 2023-03-25
    • 2019-10-26
    • 2021-03-15
    • 2016-05-28
    • 2021-05-23
    相关资源
    最近更新 更多