spring boot 测试无法注入 TestRestTemplate 和 MockMvc

Posted

技术标签:

【中文标题】spring boot 测试无法注入 TestRestTemplate 和 MockMvc【英文标题】:spring boot test unable to inject TestRestTemplate and MockMvc 【发布时间】:2017-01-05 21:56:56 【问题描述】:

我正在使用弹簧靴1.4.0.RELEASE。我正在为我的控制器类编写测试。我得到以下异常。

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.concur.cognos.authentication.service.ServiceControllerITTest': Unsatisfied dependency expressed through field 'restTemplate': No qualifying bean of type [org.springframework.boot.test.web.client.TestRestTemplate] found for dependency [org.springframework.boot.test.web.client.TestRestTemplate]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: @org.springframework.beans.factory.annotation.Autowired(required=true); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.boot.test.web.client.TestRestTemplate] found for dependency [org.springframework.boot.test.web.client.TestRestTemplate]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: @org.springframework.beans.factory.annotation.Autowired(required=true)

这是我的测试课

public class ServiceControllerITTest extends ApplicationTests 

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private MockMvc mvc;

    @Test
    public void exampleTest() throws Exception 
         // test
    

ApplicationTests.java

@RunWith(SpringRunner.class)
@SpringBootTest
@WebAppConfiguration
//@DirtiesContext
public class ApplicationTests 

    @Autowired
    Environment env;

    @Test
    public void contextLoads() 

    


【问题讨论】:

【参考方案1】:

TestRestTemplate 只有在 @SpringBootTest 配置了 webEnvironment 时才会自动配置,这意味着它会启动 Web 容器并侦听 HTTP 请求。例如:

@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)

【讨论】:

我添加了。现在我得到java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext 您还在尝试自动连接TestRestTemplateMockMvc 吗?这样做没有意义。您应该使用其中一种。 @AndyWilkinson 我发现了相同的行为(注入其中一个或两个),并且文档明确指出 @SpringBootTest 的默认值是 MOCK @chrylis 正如我上面所说,你需要使用RANDOM_PORT 才能注入TestRestTemplate @avinesh 其他 cmets 已经解释了为什么它没有解决 MockMvc。在同一个测试中使用TestRestTemplateMockMvc 是没有意义的。一种是使用嵌入式 servlet 容器通过 HTTP 测试服务,另一种是使用模拟 servlet 容器在没有 HTTP 的情况下测试服务。【参考方案2】:

如果您阅读 SpringBootTest 注解的 java 文档,它会说注解提供以下功能(此处未列出所有功能,仅列出与问题相关的功能。)

提供对不同 webEnvironment 模式的支持,包括启动在定义或随机端口上侦听的完全运行的 Web 服务器的能力。 注册 TestRestTemplate 和/或 WebTestClient bean 以用于 Web 测试,这些测试使用完全运行的 Web 服务器侦听定义或随机端口。

所以 @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) 提供了自动装配 TestRestTemplate 的能力,因为它启动了一个完全运行的 Web 服务器 [正如 @AndyWilkinson 的回答中提到的那样]。

但是如果你想在同一个 TestClass 中自动装配 MockMvc 然后使用 @AutoConfigureMockMvc 在 TestClass 上注解。

这是一个测试类的样子:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class SBTest 
    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private MockMvc mvc;

   // tests

【讨论】:

【参考方案3】:

要使用它,请不要使用已弃用的 TestRestTemplate。

已弃用:

import org.springframework.boot.test.TestRestTemplate;

正确:

import org.springframework.boot.test.web.client.TestRestTemplate;

然后你可以在你的类中使用@Autowired注解:

@Autowired
private TestRestTemplate restTemplate;

不要使用:

@Autowired
private MockMvc mvc;

两者一起不起作用。

【讨论】:

【参考方案4】:

根据Spring boot documentation:

您还可以在非@WebMvcTest(例如SpringBootTest)中自动配置MockMvc,方法是使用@AutoConfigureMockMvc 对其进行注释。

【讨论】:

这个答案帮助了我的@WebMvcTest(Spring Boot 2.5.5)。我刚刚在我的测试课上添加了@AutoConfigureWebClient,然后我遇到的UnsatisfiedDependencyException 不见了,谢谢。

以上是关于spring boot 测试无法注入 TestRestTemplate 和 MockMvc的主要内容,如果未能解决你的问题,请参考以下文章

无法在使用 @ExtendWith(SpringExtension.class) 运行的 Spring Boot 单元测试中注入应用程序上下文

如何在 Spring Boot 中将属性注入测试类?

Spring boot下@Autowired 注入为 NULL的问题

Spring Boot 测试:bean 未注入

Spring Boot 中的 Junit 测试不注入服务

Java - Spring boot - 集成测试 - TestEntityManager 没有被注入