代码之家  ›  专栏  ›  技术社区  ›  michele

Junit Spring避免加载两次应用程序上下文数据源

  •  0
  • michele  · 技术社区  · 7 年前

    我有以下配置类:

    @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脚本。

    谢谢

    4 回复  |  直到 7 年前
        1
  •  4
  •   Guillaume Husta    7 年前

    Integration Testing .

    @Transactional Transaction Management .

    ApplicationContext 对于每个测试类,可以使用缓存,如下所述: Context Caching .

    用于与的集成测试 ,您还可以找到以下文档: Testing Data Access Logic with an Embedded Database . 上一链接中与您的用例相匹配的注释:

    在测试套件中,考虑使用Spring TestCurror框架 并在春季将嵌入式数据库配置为bean ApplicationContext,如通过创建嵌入式数据库中所述

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

        2
  •  3
  •   Guillaume Husta    7 年前

    另一个很好的提示是我从 弹簧靴 Embedded Database Support :

    他们说:

    整个测试套件将重用相同的数据库,而不考虑 您使用的应用程序上下文数。如果你想确定 每个上下文都有一个单独的嵌入式数据库,您应该设置

    所以要做到每一个 EmbeddedDatabase 唯一,您可以尝试使用以下方法创建它们:

    EmbeddedDatabase db = new EmbeddedDatabaseBuilder()
                          .generateUniqueName(true)
                          ...
                          .build();
    
        3
  •  2
  •   Jose Luis    7 年前

    @测试类中的DirtiesContext(classMode=classMode.AFTER\u CLASS)

        4
  •  1
  •   Dave G    7 年前

    因此,这失败的原因是,当您作为clean/install的一部分运行测试时,数据库(H2)驻留在内存中。在运行第一个测试后,已执行创建/插入脚本。在此点之后的任何后续测试执行都将导致相同脚本的重新执行,并且会发生错误。

    使用 DROP TABLE IF EXISTS <table name>; . 这将确保删除该表,然后重新创建该表。

    :我不知道你为什么指定 AnnotationConfigContextLoader 明确地我想,没有这个,跑步者 SpringJUnit4ClassRunner