9

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

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

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

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

}

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

然而 customerServiceImpl 是这个 bean:

@Component
public class CustomerServiceImpl  implements CustomerService {
}

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

}

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

4

2 回答 2

1

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

@Bean
CustomerService customerService{
    return null;
}

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

于 2017-07-26T14:06:01.373 回答
0

@DataJpaTest不加载@Component@Service...默认情况下,只有@Repository配置 Spring 数据 JPA 所需的内部东西。

在您的测试中,您可以加载任何@Configuration您需要的内容,并且在您的情况下,您加载@ABMH2Congfiguration执行一个@ComponentScan这就是 Spring 尝试加载您的CustomerService.

您应该只扫描@Repository此配置类中的 ,并扫描其他@Component, @Service... 在另一个@Configuration类似DomainConfiguration. 区分不同类型的配置始终是一个好习惯。

于 2021-08-12T10:23:36.617 回答