将@WebMvcTest 与spring-boot 一起使用时如何排除@Configuration class?
How to exclude a @Configuration class when using @WebMvcTest with spring-boot?
我正在为休息控制器编写 junits。我只想加载与控制器相关的最小上下文,我认为这就是 @WebMvcTest
加载上下文的方式。但是 junit 正在加载完整的 Spring 上下文并且由于无法创建某些 bean 而失败。
我搜索并通读了许多关于 Whosebug 的问题,none 解决方案排除了特定配置。在为控制器编写 junits 时如何加载最小上下文?或者有什么方法可以排除某些配置 classes 吗?我正在使用 Spring-boot 2.2.2.RELEASE、Java 8 和 Junit 4.
Junit(我试图排除加载某些 bean 和配置但它不起作用):
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = OrderController.class, excludeFilters = {@Filter(classes = Configuration.class), @Filter(type = FilterType.REGEX, pattern = "com\.foo\..*")})
@TestPropertySource(properties = { "spring.cloud.config.server.bootstrap:false" })
public class OrderControllerTest {
@MockBean
private OrderService orderService;
@Autowired
private MockMvc mockMvc;
@Test
public void test() throws Exception {
mockMvc.perform(get("/internal/order/123"));
// Further code to verify the response
}
}
控制器
@Slf4j
@Validated
@RestController
@RequestMapping("/internal")
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping(value = "/order/{orderId}", produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<RegularContributionOrder> retrieveRegularContributionOrder(@NotNull @PathVariable("orderId") String orderId)
throws OrderNotFoundException {
RegularContributionOrder order = orderService.retrieve(orderId);
return new ResponseEntity<RegularContributionOrder>(order, HttpStatus.OK);
}
}
我想从上下文加载中排除的配置class
@Slf4j
@Configuration
@EnableAspectJAutoProxy
@ImportResource({ "classpath:spring/service-config-one.xml", "classpath:spring/service-config-two.xml" })
public class OrderServiceConfig {
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:resourcebundles/error-messages.properties");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
return mapper;
}
}
Spring 开机主class:
@EnableJms
@EnableAspectJAutoProxy
@ComponentScan(basePackages = { "com.foo.services", "com.bar" })
@SpringBootApplication(exclude = { SomeConfiguration.class})
public class BootApplication extends SpringBootServletInitializer {
@Override
protected final SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
return application.sources(BootApplication .class);
}
public static void main(final String[] args) {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
SpringApplication.run(BootApplication.class, args);
}
}
当您的测试 class 位于测试文件夹中并且 运行 具有 "test" 配置文件时,您的真实配置 class 将被排除。这是我如何配置 spring 启动测试的示例。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = IntegrationApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@ActiveProfiles("test")
public class MyControllerTest {
=================================
@SpringBootApplication
public class IntegrationApplication {
public static void main(String[] args) {
SpringApplication.run(IntegrationApplication.class, args);
}
您对 @ComponentScan
的使用已禁用 @WebMvcTest
用来限制通过扫描找到的组件类型的过滤器。
您应该从主应用程序 class 中删除 @ComponentScan
并改用 @SpringBootApplication
上的 basePackages
属性。
您还应将 @EnableJms
和 @EnableAspectJAutoProxy
移动到单独的 @Configuration
class,以便在使用 @WebMvcTest
时不会启用它们。或者,您可以完全删除它们,因为它们已被 Spring 启动的自动配置覆盖。
我正在为休息控制器编写 junits。我只想加载与控制器相关的最小上下文,我认为这就是 @WebMvcTest
加载上下文的方式。但是 junit 正在加载完整的 Spring 上下文并且由于无法创建某些 bean 而失败。
我搜索并通读了许多关于 Whosebug 的问题,none 解决方案排除了特定配置。在为控制器编写 junits 时如何加载最小上下文?或者有什么方法可以排除某些配置 classes 吗?我正在使用 Spring-boot 2.2.2.RELEASE、Java 8 和 Junit 4.
Junit(我试图排除加载某些 bean 和配置但它不起作用):
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = OrderController.class, excludeFilters = {@Filter(classes = Configuration.class), @Filter(type = FilterType.REGEX, pattern = "com\.foo\..*")})
@TestPropertySource(properties = { "spring.cloud.config.server.bootstrap:false" })
public class OrderControllerTest {
@MockBean
private OrderService orderService;
@Autowired
private MockMvc mockMvc;
@Test
public void test() throws Exception {
mockMvc.perform(get("/internal/order/123"));
// Further code to verify the response
}
}
控制器
@Slf4j
@Validated
@RestController
@RequestMapping("/internal")
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping(value = "/order/{orderId}", produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<RegularContributionOrder> retrieveRegularContributionOrder(@NotNull @PathVariable("orderId") String orderId)
throws OrderNotFoundException {
RegularContributionOrder order = orderService.retrieve(orderId);
return new ResponseEntity<RegularContributionOrder>(order, HttpStatus.OK);
}
}
我想从上下文加载中排除的配置class
@Slf4j
@Configuration
@EnableAspectJAutoProxy
@ImportResource({ "classpath:spring/service-config-one.xml", "classpath:spring/service-config-two.xml" })
public class OrderServiceConfig {
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:resourcebundles/error-messages.properties");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
return mapper;
}
}
Spring 开机主class:
@EnableJms
@EnableAspectJAutoProxy
@ComponentScan(basePackages = { "com.foo.services", "com.bar" })
@SpringBootApplication(exclude = { SomeConfiguration.class})
public class BootApplication extends SpringBootServletInitializer {
@Override
protected final SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
return application.sources(BootApplication .class);
}
public static void main(final String[] args) {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
SpringApplication.run(BootApplication.class, args);
}
}
当您的测试 class 位于测试文件夹中并且 运行 具有 "test" 配置文件时,您的真实配置 class 将被排除。这是我如何配置 spring 启动测试的示例。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = IntegrationApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@ActiveProfiles("test")
public class MyControllerTest {
=================================
@SpringBootApplication
public class IntegrationApplication {
public static void main(String[] args) {
SpringApplication.run(IntegrationApplication.class, args);
}
您对 @ComponentScan
的使用已禁用 @WebMvcTest
用来限制通过扫描找到的组件类型的过滤器。
您应该从主应用程序 class 中删除 @ComponentScan
并改用 @SpringBootApplication
上的 basePackages
属性。
您还应将 @EnableJms
和 @EnableAspectJAutoProxy
移动到单独的 @Configuration
class,以便在使用 @WebMvcTest
时不会启用它们。或者,您可以完全删除它们,因为它们已被 Spring 启动的自动配置覆盖。