Spring TestRestTemplate 未正确自动装配

Posted

技术标签:

【中文标题】Spring TestRestTemplate 未正确自动装配【英文标题】:Spring TestRestTemplate not autowiring correctly 【发布时间】:2017-11-15 12:24:20 【问题描述】:

我目前正在使用 Spring Boot 1.5.4 以及 Junit 5 和 Java 8。

我想使用 Junit 的 ParameterizedTest 对存储在 csv 文件中的多个条目设置集成测试。

代码如下:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class MatchingIT 

    @Autowired
    private TestRestTemplate template;

    @ParameterizedTest
    @MethodSource(names = "vehicles")
    void nonRegressionTests(EDIVehicle vehicle) 
        ResponseEntity<Vehicle> v = template.getForEntity("/match/" + vehicule.getId(), Vehicle.class);
        Assert.assertNotNull(v);
    

    private static Stream<EDIVehicle> vehicles() throws IOException 
        InputStream is = new ClassPathResource("/entries.csv").getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        return br.lines().map(toVehicle);
    

    private static Function<String, EDIVehicle> toVehicle = (line) -> 
        String[] p = line.split("\\|");
        return new EDIVehicle(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12]);
    ;

我从文档中知道:

如果您使用@SpringBootTest 注解,TestRestTemplate 将自动可用并且可以@Autowired 到您的测试中。

问题是我确实使用了 SpringBootTest 注释,但是当我运行测试时,TestRestTemplate 始终为空。也许我错过了什么。

编辑:我在添加 @RunWith(SpringRunner.class) 注释时确实遇到了完全相同的问题

【问题讨论】:

您使用的是 JUnit 5 吗?我认为 Spring Boot 还没有为 JUnit 5 提供一流的支持。有一个扩展可以帮助你:github.com/sbrannen/spring-test-junit5 你能检查你从哪个包导入TestRestTemplate吗? org.springframework.boot.test.web.clientorg.springframework.boot.test ? @harshavmb 我使用的是 org.springframework.boot.test.web.client 而不是已弃用的。 @LucasP 我会使用 JUnit 5 是的。我将尝试使用 JUnit 4 以确保问题不是来自 JUnit 版本。 @Lucas 我通过使用您提到的依赖项解决了我的问题。谢谢!问题是,在执行“mvn clean install”时,我的测试不是由 maven 运行的 【参考方案1】:

我认为您缺少 @RunWith(SpringRunner.class) 并确保初始化上下文的类(通常是包含 main 方法的类)具有 @SpringBootApplication 注释(否则 @SpringBootTest 找不到上下文为测试加载。

【讨论】:

正如我对 David Florez 所说,即使使用 @RunWith(SpringRunner.class) 注释,我也确实遇到了完全相同的问题。我正在调查上下文。 我认为 @RunWith(SpringRunner.class) 可能是解决您的问题的方法之一。 SpringRunner 和 SpringBootTest 的区别在***.com/questions/58901288/…【参考方案2】:

@SpringBootTest 与 JUnit 5 不完全兼容。但是您可以使用下一个测试声明来解决此问题:

@RunWith(JUnitPlatform.class)
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
class MatchingIT ...

注意:您必须将您的spring-boot-starter-test 版本升级到2.0.0.M1 才能使用org.springframework.test.context.junit.jupiter.SpringExtension(最简单的方法是使用start.spring.io 生成2.0.0.M1 -dependent 项目并从那里获取所需的 maven/gradle 依赖项)。

【讨论】:

我不确定我是否已经想在我的项目中使用 Spring 5。如果我找不到任何其他解决方案,我可能会尝试,我会回复您。 整个项目不需要使用 Spring 5。您仅在测试中需要它。您已经在使用尚未发布的 Junit 5 - 添加一个未发布的测试依赖项应该不是问题。【参考方案3】:

我最终使用了来自以下 repo 的依赖项:github.com/sbrannen/spring-test-junit5 如上所述 @LucasP

由于在 Spring 4.3 及以下版本中没有对 JUnit 5 的一流支持,它帮助我通过在我的测试类上使用 @ExtendWith(SpringExtension.class) 正确地自动装配 Spring TestRestTemplate。

下一步是直接使用 Spring Boot 2.0 来更好地支持 JUnit 5。

【讨论】:

以上是关于Spring TestRestTemplate 未正确自动装配的主要内容,如果未能解决你的问题,请参考以下文章

spring boot 测试无法注入 TestRestTemplate 和 MockMvc

使用 TestRestTemplate 时出现异常

使用 TestRestTemplate 进行 Multipart POST 请求的集成测试返回 400

Spring boot 1.4.2 单元测试配置

Spring Data Rest 不能做集成测试?

哪种是对 Spring Boot Rest API 进行端到端测试的最佳方法? [关闭]