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

Spring boot 如何在SpringBootTest中的每次测试后重置@Repository?,spring-boot,spring-boot-test,spring-repositories,Spring Boot,Spring Boot Test,Spring Repositories,我正试图为我新创建的@Repository类进行集成测试,但是没有任何运气一起运行所有测试。如果我分别运行每个测试-它们通过,但是如果我运行整个测试类-两个测试失败,它们试图在H2中按id查找一行(用于测试的单独db),但没有找到 下面是我的测试课程: package com.vaidas.development.gradecalculatorbackend.repositories; import com.vaidas.development.gradecalculatorbackend.m

我正试图为我新创建的@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注释,我希望这些注释能够重置DB内容
  • 在每个测试中都使用@Before和@After注释,但它们似乎是异步操作的,并没有等待DB完成添加/删除实例
未能通过的测试包括:

shouldInsertAndFindOne() {
shouldUpdate() {
上述每一项都会引发以下错误:

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

有人能解释为什么会发生这种情况,以及在每次测试之前重置H2测试db的正确方法是什么吗?

我不知道这是否正确,但我通常只是在
@before
-注释方法中添加
repositoryName.deleteAll()

@Before
public void before() {
    moduleRepository.deleteAll();
    moduleRepository.flush();
}
此方法将在每个带
@Test
-注释的方法之前运行,并将确保
moduleRepository
为空


此外,该
@Transactional
注释可能是问题的根源。您是否尝试过在没有注释的情况下使用
@Before
方法?或者在类级别添加一个
@Transactional
如何?

谢谢您的帮助,但事实证明我没有从存储库中的“insertModule”方法检索生成的密钥。我分配了NamedParameterJdbcTemplate.update方法的返回值,现在我使用GeneratedKeyHolder来检索这个值。我犯了个愚蠢的错误。另外,我在类级别使用@Transactional将db状态回滚到原始状态。谢谢你的意见!