为什么spring boot的DataJpaTest扫描@Component

Mic*_*son 9 spring spring-boot spring-boot-test

确信没有人问过这个问题,但是通过阅读 Spring 文档和测试实用程序,我发现了这个注释,并认为我会开始使用它。通读小字,我读到:

常规的@Component bean 不会加载到 ApplicationContext 中。

这听起来不错,我什至喜欢使用 H2 的想法,除了我发现我想要使用的实体具有目录和模式修饰符,而默认的 H2 我不知道如何支持它。我为测试分支创建了一个 H2 数据源并使用它并覆盖替换。我结束了

@RunWith(SpringRunner.class)
@ContextConfiguration(classes=ABCH2Congfiguration.class)
@DataJpaTest
@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE)
public class StatusRepositoryTest {

}
Run Code Online (Sandbox Code Playgroud)

但是我的测试失败了原因:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有符合类型的bean。这导致:创建名为“customerServiceImpl”的 bean 时出错:依赖项不满足。

但是 customerServiceImpl 是这个 bean:

@Component
public class CustomerServiceImpl  implements CustomerService {
}
Run Code Online (Sandbox Code Playgroud)

那就是@Component。DataJpaTest 的细则说它不加载@Components。为什么它会这样做,从而导致测试失败?

正如凯尔和尤金在下面问的那样,剩下的就是:

package com.xxx.abc.triage;
@Component
public interface CustomerService {
}

Configuration
@ComponentScan("com.xxx.abc")
@EnableJpaRepositories("com.xxx.abc")
//@Profile("h2")
public class ABMH2Congfiguration {

    @Primary
    @Bean(name = "h2source")
    public DataSource dataSource() {
        EmbeddedDatabase build = new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).setName("ABC").addScript("init.sql").build();
        return build;
    }

    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        HibernateJpaVendorAdapter bean = new HibernateJpaVendorAdapter();
        bean.setDatabase(Database.H2);
        bean.setShowSql(true);
        bean.setGenerateDdl(true);
        return bean;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
        LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
        bean.setDataSource(dataSource);
        bean.setJpaVendorAdapter(jpaVendorAdapter);
        bean.setPackagesToScan("com.xxx.abc");
        return bean;
    }

    @Bean
    public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
    }

}
Run Code Online (Sandbox Code Playgroud)

只是为了澄清这个问题,为什么 @Component 被加载到 @DataJpaTest 中的上下文中?

小智 1

@ComponentScan自动将所有找到的@Component内容注入@Service上下文中。您可以通过单独覆盖它@Bean

@Bean
CustomerService customerService{
    return null;
}
Run Code Online (Sandbox Code Playgroud)

或者从和中删除@Component注释,但您应该在生产中添加CustomerServiceCustomerServiceImpl@Bean@Configuration