Spring 交易 - 确保测试和生产中的可预测行为

Spring Transactional - Ensure predictable behavior in tests and prod

我想测试一下我的 UserService 的注册方法,如下所示。

@Transactional
override fun register(userRegistration: UserRegistration): AuthDto {
    val user = userRegistration.toUserEntity()
    return try {
        val entity = userRepository.save(user)
        //entityManager.flush()
        val id = entity.getIdOrThrow().toString()
        val jwt = jwtService.createJwt(id)
        entity.toAuthDto(jwt)
    } catch (ex: PersistenceException) {
        throw UserRegistrationException(userRegistration.username, ex)
    }
}

由于 User 实体的 userName 上有一个唯一索引,我想断言当注册一个已经存在的用户名时会抛出异常。在这种情况下,我尝试捕获抛出的任何异常并重新抛出我自己的异常。

现在我的测试只需要一个现有的用户名并调用注册。

@Test fun `register twice - should throw`() {
    val existingRegistration = UserRegistration(testUserAdminName, "some", "test")

    assertThrows<UserRegistrationException> {
        userService.register(existingRegistration)
        //entityManager.flush()
    }
}

但是,不会抛出任何异常,除非我通过实体管理器显式刷新。但是我怎样才能抛出自己的异常呢?

我应该在 UserService 中使用 flush 吗?

答案来自M. Deinum。

Flushing is done on commit and that is also where the exception is being thrown. So if you want to directly get an exception you will have to call saveAndFlush instead of save (assuming you are using the JpaRepository as a base for your own repository)

我切换到 JpaRepository,现在使用 saveAndFlush