[英]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.