首页 > 解决方案 > Junit Spring 避免加载两次应用程序上下文数据源

问题描述

我有这个配置类:

@ComponentScan(
        basePackages = { 
                "mypackage.controller",
                "mypackage.service",
                "mypackage.repository" 
        }
)
@TestPropertySource(locations="classpath:configuration.properties")
@Import({
    H2Configuration.class
})
public class TestConfiguration {
}

@Configuration
public class H2Configuration {

    @Bean
    public DataSource dataSource() throws SQLException {
        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
        EmbeddedDatabase db = builder
                .setType(EmbeddedDatabaseType.H2)
                .addScript("h2/create.sql")
                .addScript("h2/insert.sql")
                .build();
        db.getConnection().setAutoCommit(false);
        return db;
    }

}

我有这两类测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class, classes = { TestConfiguration.class })
public class FirstRepositoryTest {

    @Autowired
    MyFirstRepositoryImpl repository;

    @Before
    public void initTest() {
    }

    @Test(expected = NullPointerException.class)
    public void testNullRecords() {
        repository.foo(null, null);
    }
}


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class, classes = { TestConfiguration.class })
public class SecondRepositoryTest {

    @Autowired
    MySecondRepositoryImpl repository;

    @Before
    public void initTest() {
    }

    @Test(expected = NullPointerException.class)
    public void testSomethingNullRecords() {
        repository.something(null, null);
    }
}

如果我为每个班级运行一次 junit 测试,一切顺利。

在全新安装阶段测试失败,因为应用程序上下文被初始化了两次。

例如,它尝试创建两次 h2 表并执行两次 insert.sql 脚本。

我必须做些什么来初始化 h2 数据库和应用程序上下文一次?

谢谢

标签: javaspringapplicationcontext

解决方案


我认为您可以开始查看有关集成测试的 Spring 文档。

将事务测试用于集成测试 ( @Transactional) 也是一种很好的做法,它会在每个测试结束时回滚:请参阅事务管理

为了避免为每个测试类重新创建的成本,ApplicationContext可以使用缓存,如下所述:上下文缓存

对于嵌入式数据库的集成测试,您还可以找到文档:使用嵌入式数据库测试数据访问逻辑。上一个链接中的注释,与您的用例匹配:

但是,如果您希望创建一个在测试套件中共享的嵌入式数据库,请考虑使用 Spring TestContext Framework 并将嵌入式数据库配置为 Spring ApplicationContext 中的 bean,如使用 Spring XML 创建嵌入式数据库和创建一个以编程方式嵌入数据库。

我希望你能找到一些有用的参考资料。


推荐阅读