我用定义了一个测试
@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.
我缺少什么注释?
编辑:
为什么从SpringBoot应用程序中的测试中删除WebMvcTest注释会导致ComponentScan失败
因为您没有以Spring的IoC/Dependency注入可以正确工作的方式对类进行注释。
既然答案很清楚,下面有几个建议供您尝试。它们可能工作,也可能不工作,这取决于您的项目和依赖关系等的组合方式。
结束编辑:
这个特殊的测试不需要任何MVC功能。
若您不需要所有MVC,但确实想要自动配置,则应该考虑为测试使用一个更直接的自动配置注释。例如,您似乎正在使用某个数据系统进行测试。也许@DataJpaTest或@JdbcTest注释将提供一种更精简的方法。这些将启用自动配置(IoC和依赖项注入(。
我缺少什么注释
如上所述,您缺少的注释是@Configuration
这与直觉相反,因为这不是一个配置类。但是,如果没有适当的注释来实现依赖项注入,这是实现这一点的唯一方法。为什么?
来自文档:
public@interface组件扫描
Configures component scanning directives for use with @Configuration classes.
所以您的选择是:
- 按照上面的建议使用不同的自动配置注释
- 添加
@Configuration
注释