测试JPA Spring 3.1的最佳方法

测试JPA Spring 3.1的最佳方法,spring,junit4,spring-data-jpa,spring-test,Spring,Junit4,Spring Data Jpa,Spring Test,我已经为我的Spring3.1.1/JPA/Hibernate4Web应用编写了几个JPA存储库、服务和支持类。然而,我真的很想为它编写一些单元和集成测试(我知道,你应该先编写这些测试)。我使用的是JavaConfig而不是XML,所以我想知道最好的测试方法。以下是我试图解决的一个特殊问题: 我有一个@Configuration,它声明了DataSource、JpaTransactionManager、LocalContainerEntityManagerFactoryBean以及我的所有职责。

我已经为我的Spring3.1.1/JPA/Hibernate4Web应用编写了几个JPA存储库、服务和支持类。然而,我真的很想为它编写一些单元和集成测试(我知道,你应该先编写这些测试)。我使用的是JavaConfig而不是XML,所以我想知道最好的测试方法。以下是我试图解决的一个特殊问题:

我有一个@Configuration,它声明了DataSource、JpaTransactionManager、LocalContainerEntityManagerFactoryBean以及我的所有职责。显然,我不想为集成测试启动所有这些,所以我想我可以使用EmbeddedDatabase和H2来创建内存中的数据库,填充值,然后使用我的存储库对其进行测试。然而,我所看到的文档并没有帮助我把这些放在一起。我有这个:

@RunWith( SpringJUnit4ClassRunner.class )
public class TestMenuService {

    private EmbeddedDatabase database;

    @Autowired
    private MenuRepository menuRepository;

    @Before
    public void setUp() throws Exception {
        database = new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).setName("myschema")
                .addScript("classpath:schema.sql").build();

        menuRepository = new MenuRepository();
        Assert.assertNotNull(database);
    }
但是menuRepository没有实例化,所以我尝试创建@Configuration的测试版本

@Configuration } )
@ComponentScan( basePackages = { "com.mycompany.service"} )
@EnableTransactionManagement
@ImportResource( "classpath:applicationContext.xml" )
@PropertySource( "classpath:test-application.properties" )
public class TestEdmConfiguration {

    @Bean
    MenuRepository menuRepository() {
        return new MenuRepository();
    }
My test-applicationContext.xml

<jpa:repositories base-package="com.mycompany.servce.repository"/>
但这需要我创建上面提到的所有数据源等。看起来我只是复制了这一个的所有支持bean


有没有一种方法可以将reposository和embeddeddatabase隔离到我的测试中,而不需要所有其他依赖项?

如果您想在完整集成测试中测试存储库,我会想象您需要设置其他所有内容,如EntityManagerFactory、PlatformTransactionManager等

由于您使用的是Spring3.1,我建议您使用bean概要文件来实现这一点

我将创建两个概要文件,一个用于测试,一个用于应用程序,每个概要文件都提供一个数据源

@Configuration
@Profile("test")
public class EmbeddedDataSource {

  @Bean
  public DataSource dataSource() {
    // Return a H2 datasource
  }

}

@Configuration
@Profile("application")
public class ApplicationDataSource {

  @Bean
  public DataSource dataSource() {
    // Return a normal datasource
  }

}
您可以创建一个启动spring上下文的测试,如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = { MyConfigClass.class })
@ActiveProfiles(profiles = {"test"})
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class TestRepository {



}

在这里,您可以指定测试活动的配置文件。

我将尝试这种方法,但我希望我可以使用embeddeddatabase、jpa和service,而不必为集成测试实例化整个堆栈。单元测试这些组件的最佳方法是什么?单元测试与集成测试有很大的不同,我相信您也知道。集成测试意味着针对整个堆栈进行测试。要对bean进行单元测试,您应该使用Mockito或类似工具在手动实例化它时将模拟依赖项传递给constructor。然后可以单独测试行为。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = { MyConfigClass.class })
@ActiveProfiles(profiles = {"test"})
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class TestRepository {



}