本文介绍了Spring Boot @WebMvcTest 与 @SpringBootTest的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的健康控制器,定义如下:

@RestController@RequestMapping("/admin")公共类 AdminController {@Value("${spring.application.name}")字符串服务名称;@GetMapping("/health")字符串 getHealth() {返回服务名称 + "启动并运行";}}

以及测试它的测试类:

@WebMvcTest(RedisController.class)类 AdminControllerTest {@自动连线私有 MockMvc mockMvc;@测试public void healthShouldReturnDefaultMessage() 抛出异常 {this.mockMvc.perform(get("/admin/health")).andDo(print()).andExpect(status().isOk()).andExpect(content().string(containsString(live-data-service up and running")));}}

运行测试时,我收到以下错误:

***************************应用程序无法启动****************************说明:com.XXXX.LiveDataServiceApplication 中的字段配置需要一个无法找到的com.XXXXX.AppConfiguration"类型的 bean.注入点有以下注释:- @org.springframework.beans.factory.annotation.Autowired(required=true)行动:考虑在您的配置中定义一个com.XXXX.AppConfiguration"类型的 bean.

这里是 AppConfiguration.java 定义在与主 Spring Boot 应用程序类相同的包中:

@Configuration@EnableConfigurationProperties@配置属性公共类 AppConfiguration {@Value("${redis.host}")私有字符串 redisHost;@Value("${redis.port}")私有 int redisPort;@Value("${redis.password:}")私有字符串 redisPassword;...//getter 和 setter 来到这里

主类:

@SpringBootApplication公共类 LiveDataServiceApplication {@自动连线私有 AppConfiguration 配置;公共静态无效主(字符串 [] args){SpringApplication.run(LiveDataServiceApplication.class, args);}@豆公共RedisConnectionFactory redisConnectionFactory() {RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration(configuration.getRedisHost(), configuration.getRedisPort());redisConfiguration.setPassword(configuration.getRedisPassword());返回新的生菜连接工厂(redisConfiguration);}}

如果我修改测试类中的注解如下,测试通过:

@SpringBootTest@AutoConfigureMockMvc类 AdminControllerTest {....

我错过了什么?

解决方案

@WebMvcTest@SpringBootTest

的用法你应该明白

@WebMvcTest : 注解只是实例化 web 层而不是整个上下文,所以控制器类中的所有依赖都应该被模拟,你可以看看 文档

Spring Boot 仅实例化 web 层而不是整个上下文.在具有多个控制器的应用程序中,您甚至可以使用例如 @WebMvcTest(HomeController.class).

要求仅实例化一个控制器

我们使用@MockBean 为 GreetingService 创建和注入一个模拟(如果你不这样做,应用程序上下文将无法启动)

SpringBootTest : Spring Boot 测试注解实际加载测试环境的应用上下文

@SpringBootTest 注释告诉 Spring Boot 寻找一个主要的配置类(例如一个带有 @SpringBootApplication 的类)并使用它来启动一个 Spring 应用程序上下文.

I have a simple health controller defined as follows:

@RestController
@RequestMapping("/admin")
public class AdminController {

    @Value("${spring.application.name}")
    String serviceName;

    @GetMapping("/health")
    String getHealth() {
        return serviceName + " up and running";
    }
}

And the test class to test it:

@WebMvcTest(RedisController.class)
class AdminControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void healthShouldReturnDefaultMessage() throws Exception {
        this.mockMvc.perform(get("/admin/health"))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(content().string(containsString("live-data-service up and running")));
    }
}

When running the test, I'm getting the below error:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field configuration in com.XXXX.LiveDataServiceApplication required a bean of type 'com.XXXXX.AppConfiguration' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'com.XXXX.AppConfiguration' in your configuration.

Here is AppConfiguration.java defined in the same package as the main spring boot app class:

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties
public class AppConfiguration {

    @Value("${redis.host}")
    private String redisHost;

    @Value("${redis.port}")
    private int redisPort;

    @Value("${redis.password:}")
    private String redisPassword;
...
// getters and setters come here

Main class:

@SpringBootApplication
public class LiveDataServiceApplication {

    @Autowired
    private AppConfiguration configuration;

    public static void main(String[] args) {
        SpringApplication.run(LiveDataServiceApplication.class, args);
    }

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration(configuration.getRedisHost(), configuration.getRedisPort());
        redisConfiguration.setPassword(configuration.getRedisPassword());
        return new LettuceConnectionFactory(redisConfiguration);
    }
}

If I modify the annotation in the test class as follows, the test pass:

@SpringBootTest
@AutoConfigureMockMvc
class AdminControllerTest {
....

What am I missing?

解决方案

You should understand the usage of @WebMvcTest and @SpringBootTest

@WebMvcTest : annotation is only to instantiates only the web layer rather than the whole context, so all dependencies in controller class should be mocked, you can look at the documentation

SpringBootTest : Spring boot test annotation actual load the application context for test environment

这篇关于Spring Boot @WebMvcTest 与 @SpringBootTest的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 20:53
查看更多