在SpringBootTest中的每次测试后,如何重置@Repository?

时间:2019-04-27 15:25:52

标签: spring-boot spring-boot-test spring-repositories

我正在尝试对我新创建的@Repository类进行集成测试,但是不能同时运行所有测试。如果我分别运行每个测试-它们通过了,但是如果我运行了整个测试类-两个测试都失败了,尝试在H2中按ID查找一行(用于测试的单独db),却找不到。

这是我下面的测试课程:

package com.vaidas.development.gradecalculatorbackend.repositories;

import com.vaidas.development.gradecalculatorbackend.models.Module;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import static org.junit.Assert.assertEquals;

@RunWith(SpringRunner.class)
@SpringBootTest
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
public class ModuleRepositoryTest {

    @Autowired
    private ModuleRepository moduleRepository;

    @Test
    @Transactional
    public void shouldInsertAndFindAll() {
        // GIVEN
        Module module = new Module("Test module", null);
        int count = moduleRepository.findAll().size();

        // WHEN
        moduleRepository.insertModule(module);
        int countAfter = moduleRepository.findAll().size();

        // THEN
        assertEquals(count,countAfter - 1);
    }

    @Test
    @Transactional
    public void shouldInsertAndFindOne() {
        // GIVEN
        Module module = new Module("Test module", null);
        module = moduleRepository.insertModule(module);

        // WHEN
        Module storedModule = moduleRepository.findOne(module.getId());

        // THEN
        assertEquals(storedModule.toString(), module.toString());
    }

    @Test
    @Transactional
    public void shouldUpdate() {
        // GIVEN
        Module module = new Module("Test module", null);
        module = moduleRepository.insertModule(module);
        Module updatedModule = new Module("Test module updated", null);
        updatedModule.setId(module.getId());

        // WHEN
        moduleRepository.updateModule(updatedModule);

        // THEN
        Module foundModule = moduleRepository.findOne(updatedModule.getId());
        assertEquals(foundModule.getName(), updatedModule.getName());
    }

    @Test
    @Transactional
    public void shouldDelete() {
        // GIVEN
        Module module = new Module("Test module", null);
        module = moduleRepository.insertModule(module);

        // WHEN
        moduleRepository.deleteModule(module);

        // THEN
        assertEquals(0, moduleRepository.findAll().size());
    }
}

我尝试过的事情:

  • 使用我希望重置数据库内容的@DirtiesContext和@Transactional批注
  • 在每个测试中都使用@Before和@After批注,但是它们似乎是异步执行的,并没有等待DB完成添加/删除实例的操作

失败的测试是:

shouldInsertAndFindOne() {
shouldUpdate() {

以上每种均引发以下错误:

org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0

有人可以解释为什么会发生这种情况吗?在每次测试之前重置我的H2测试数据库的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

我不知道这是否是正确的方法,但是我通常只在带有repositoryName.deleteAll()注释的方法中添加一个@Before

@Before
public void before() {
    moduleRepository.deleteAll();
    moduleRepository.flush();
}

此方法将在每个带有@Test注释的方法之前运行,并确保moduleRepository为空。

此外,@Transactional注释可能是问题的根源。您是否尝试过没有该注释的@Before方法?还是在课程级别添加@Transactional呢?