有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在springboot中使用@WebMvcTest时,如何排除@Configuration类?

我正在为rest控制器编写junits。我只希望加载与控制器相关的最小上下文,我认为这就是@WebMvcTest加载上下文的方式。但是junit正在加载完整的Spring上下文,它失败了,因为无法创建一些bean

我已经搜索并阅读了许多关于stackoverflow的问题,没有一个解决方案能够排除特定的配置。在为控制器编写junits时,如何加载最小上下文?或者有没有办法排除某些配置类?我使用的是SpringBoot2.2.2。发行版、Java8和JUnit4

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

要从上下文加载中排除的配置类

@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 boot主类:

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

共 (2) 个答案

  1. # 1 楼答案

    当您的测试类位于测试文件夹中并使用“测试”配置文件运行时,您的真实配置类将被排除。下面是一个如何配置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);
    }
    
  2. # 2 楼答案

    使用@ComponentScan已禁用@WebMvcTest使用的筛选器,以限制通过扫描找到的组件类型

    您应该从主应用程序类中删除@ComponentScan,并在@SpringBootApplication上使用basePackages属性

    您还应该将@EnableJms@EnableAspectJAutoProxy移动到单独的@Configuration类,以便在使用@WebMvcTest时不启用它们。或者,您可以完全删除它们,因为SpringBoot的自动配置涵盖了它们