繁体   English   中英

Spring 引导@WebMvcTest 与@SpringBootTest

[英]Spring Boot @WebMvcTest vs @SpringBootTest

我有一个简单的 health controller 定义如下:

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

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

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

并测试 class 来测试它:

@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")));
    }
}

运行测试时,出现以下错误:

***************************
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.

这是AppConfiguration.java在与主 spring 启动应用程序 class 相同的 package 中定义:

@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

总机 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);
    }
}

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

@SpringBootTest
@AutoConfigureMockMvc
class AdminControllerTest {
....

我错过了什么?

你应该了解@WebMvcTest@SpringBootTest的用法

@WebMvcTest: annotation只是为了实例化web层而不是整个上下文,所以controller class中的所有依赖都应该被模拟,你可以看看文档

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

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

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

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

在 src/test/resource/application.file 示例中定义所有属性,以将 junit 5 用于 rest 层:

@ExtendWith(MockitoExtension.class)
public class RestTest {

    
    @InjectMocks
    private RestClass  restClass;
    
    
    
    private MockMvc mockMvc;
    
    @BeforeEach
    public void init() throws Exception {
        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders.standaloneSetup(restClass).build();
    }
    
    @Test
    public void test() throws Exception {
        String url = "/url";
        ResultActions resultActions = mockMvc.perform(get(url));
        resultActions.andExpect(status().isOk());

    }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM