简体   繁体   English

Spring 数据 JPA 每种方法后数据库更改不会在集成测试中回滚

[英]Spring Data JPA database changes after each method don't roll back in integration tests

I am using JUnit 5 with Spring boot 2.2.4 for integration testing my Spring Boot application code with MySQL 5.7 database but the changes that a previous test method makes to database aren't rolled back causing errors in the ones that follow. I am using JUnit 5 with Spring boot 2.2.4 for integration testing my Spring Boot application code with MySQL 5.7 database but the changes that a previous test method makes to database aren't rolled back causing errors in the ones that follow.

I've tried answers from different stackoverflow posts such as adding @Transactional (from Spring), @Rollback (method as well as class level), @TestExecutionListeners(listeners = {TransactionalTestExecutionListener.class}) .我尝试了来自不同 stackoverflow 帖子的答案,例如添加@Transactional (来自 Spring)、@Rollback(方法以及@Rollback级别)、 @TestExecutionListeners(listeners = {TransactionalTestExecutionListener.class}) I've tested these options individually (as well as in combination) but adding them in the test code together.我已经单独(以及组合)测试了这些选项,但将它们一起添加到测试代码中。

This is my test code:这是我的测试代码:

@DataJpaTest
@Transactional
@Rollback
@ExtendWith(SpringExtension.class)
@Import({UserUsecasesImpl.class})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class UserUsecasesImplINTTest {

    @Autowired
    private TestEntityManager entityManager;
    @Autowired
    @Spy
    private UserRepository userRepository;
    @Autowired
    private UserUsecases userUsecases;

    @Test
    void injectedComponentsAreNotNull(){
        assertNotNull(entityManager);
        assertNotNull(userRepository);
        assertNotNull(userUsecases);
    }

    @Test
    @Rollback
    void Create_EntityAlreadyExists_ReturnsException() {
        // set up
        User expected = UserFixture.user1.toBuilder().build();
        // entityManager.persistAndFlush(expected);
        userRepository.saveAndFlush(expected);

        // execute
        User actual = userUsecases.create(expected);

        // verify
        assertEquals(expected, actual);
        verify(userRepository).findOne(any(Example.class));
        verify(userRepository, never()).save(any(User.class));
        verifyNoMoreInteractions();
    }

    @Test
    void Find_WhenUserPresent_ReturnUser() {
        // // set up
        User expected = UserFixture.user1.toBuilder().build();
        entityManager.persistAndFlush(expected);

        // execute
        User actual = userRepository.find(expected);

        // verify
        assertEquals(expected, actual);
    }

    @Test
    // @Transactional
    void Find_WhenUserNotPresent_ReturnNull() {
        // // set up
        User expected = UserFixture.user1.toBuilder().build();
        // entityManager.persistAndFlush(UserFixture.user2.toBuilder().build());

        // execute
        User actual = userUsecases.find(expected);

        // verify
        assertNull(actual);
    }
}

UserUsecasesImpl is the class that I am trying to test which contains usecases such as creating a user, finding a user, get all users, etc. There is no special configuration anywhere else in the code. UserUsecasesImpl是我正在尝试测试的 class ,它包含创建用户、查找用户、获取所有用户等用例。代码中的其他任何地方都没有特殊配置。

Please implement following fixes and let me know if problem still there:请实施以下修复,如果问题仍然存在,请告诉我:

  1. Remove all @Transactional and @Rollback .删除所有@Transactional@Rollback Keep @DataJpaTest which by default makes all of your tests @Transactional and therefore by default will roll them all back.保留@DataJpaTest ,默认情况下使您的所有测试 @Transactional ,因此默认情况下会将它们全部回滚。
  2. don't use saveAndFlush .不要使用saveAndFlush The flush part is flushing save operation into the database and most likely causes your issue.刷新部分是将保存操作刷新到数据库中,很可能会导致您的问题。 Use save instead.改用save More here https://www.baeldung.com/spring-data-jpa-save-saveandflush更多在这里https://www.baeldung.com/spring-data-jpa-save-saveandflush
  3. If you are expecting exception assert it with assertThrows .如果您期待异常,请使用assertThrows对其进行断言。

In general try not to throw every single annotation you know into the mix at the same time.一般来说,尽量不要同时将你知道的每一个注释都扔到混合中。 Add them one at a time as you need them, try to understand what they do.根据需要一次添加一个,尝试了解它们的作用。

What is UserUseCases and why does it do most of the logic I would expect the Repository class to do?什么是 UserUseCases,为什么它会执行我希望存储库 class 执行的大部分逻辑?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM