为什么从SpringBoot应用程序的测试中删除WebMvcTest批注会导致ComponentScan失败?

时间:2018-12-05 01:23:02

标签: spring-mvc spring-boot spring-test spring-test-mvc

我定义了一个测试:

@ComponentScan(basePackages = { ... })
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { AppConfig.class })
@WebMvcTest(secure = false)
public class MyTest extends AbstractJUnit4SpringContextTests  {

     @Autowired SomeClass target;

     @Test public void test() { Assert.assertTrue(target != null); } // MCVE

}

这是我的ContextConfiguration类:

@Configuration
public class AppConfig {

    @Bean
    @ConfigurationProperties(prefix = "datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    @Bean
    ServletWebServerFactory servletWebServerFactory() {
        return new TomcatServletWebServerFactory();
    }

}

该测试工作正常,但是由于带有@WebMvcTest注释,因此在MVC初始化中浪费了很多时间。此特定测试不需要任何MVC功能。由于反复试验,注释最终在该处结束,以使@Autowired注释能够正常工作。但是现在我要删除它。

所以...我继续删除了@WebMvcTest注释。但是测试失败了,因为除非存在@ComponentScan,否则@WebMvcTest显然没有任何作用(我现在记得,这就是我添加它的原因)。

这是实际的错误消息:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type '...' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

我尝试添加@SpringBootTest,但没有区别。

相反,如果我添加@EnableAutoConfiguration,则会收到另一个错误:

java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.

我缺少什么注释?

1 个答案:

答案 0 :(得分:1)

编辑:

  

为什么从SpringBoot应用程序的测试中删除WebMvcTest注释会导致ComponentScan失败?

因为您没有以使Spring的IoC /依赖注入能够正常工作的方式对类进行注释。

现在答案很明确,这里有一些建议供您尝试。它们可能行不通,具体取决于您的项目和依赖项等的组合方式。

结束编辑:

  

此特定测试不需要任何MVC功能。

如果您不需要所有MVC,但希望自动配置,则应考虑使用更直接的auto-configuration批注之一进行测试。例如,似乎您正在使用某些数据系统进行测试。也许@DataJpaTest@JdbcTest注释将提供一种更简化的方法。这些将启用自动配置(IoC和依赖注入)。

  

我缺少什么注释?

如上所述,您缺少的注释为@Configuration

这在这里是很直观的,因为这不是配置类。但是,如果没有适当的注释使依赖注入能够发生,这是使它起作用的唯一方法。为什么?

从文档中

  

public @interface ComponentScan

  Configures component scanning directives for use with @Configuration classes.

所以您的选择是:

  1. 使用上面建议的其他自动配置注释
  2. 添加@Configuration批注