【问题标题】:Repository Test runs in isolation but fails overall (mvn test)存储库测试单独运行但整体失败(mvn 测试)
【发布时间】:2023-03-26 08:30:01
【问题描述】:

当我为 UserRepository 运行测试用例时,它会单独运行(例如,mvn test -Dtest=UserRepository.class)。

但是当我运行mvn test 时,它失败了。 我收到了java.lang.NullPointerException

我的测试类是:

@RunWith(SpringRunner.class)
@DataJpaTest
public class UserRepositoryTest {

@Autowired
private EntityManager entityManager;

@Autowired
private UserRepository userRepository;

// This validates the Hibernate Constraints
private Validator validator;

一个示例测试用例是:

@Test
public void repo_should_create_a_user() {
    User u = new User();
    u.setUserName("firstUser");
    u.setRole(User.Role.USER);
    entityManager.persist(u);

    User user = userRepository.findAll().get(0);
    Assert.assertThat( user, instanceOf(User.class) );
    assertEquals("firstUser", user.getUserName());

}

User 实体具有常规属性,例如电子邮件和密码等。此外,它还包含 created_bymodified_by 等审计功能,它们利用安全上下文来获取当前用户。

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 请完整日志消息...上下文很重要...

标签: maven unit-testing spring-boot flyway


【解决方案1】:

其中一种可能性是,当运行不同的测试时,后面的测试在第一次测试之后使数据库处于脏状态,因此如果UserRepositoryTest 在其他测试之后运行,它们可能会在数据库中留下一些垃圾。

一般来说,最好确保数据库中没有“垃圾”数据。

一种方法是在测试中使用@Transactional注解,这样如果一切都正确集成,测试期间更改的数据将在测试后自动从数据库中删除,因为Spring会回滚事务。

这将保证下一步不会得到那些垃圾。

【讨论】:

  • 绝对有意义。但是从日志中我可以看到,在没有 @Transactional 注释的情况下,操作一旦完成就会回滚。是不是 Spring Boot 自动配置了这个?
  • 我没有使用过 JPA(我们使用带有 JOOQ 的 spring),所以在我的情况下,@Transactional 是强制性的,它应该放在所有测试中。我认为它与 JPA 的行为也相同。无论如何,您可以在失败的测试中添加几个“select”-s,以检查“意外”数据是否确实在数据库中,可能根据数据的性质,您将了解它的确切来源。
【解决方案2】:

事实证明,我在我的 User 类中使用数据库审计属性,而 User 类中的 created_bymodified_by 属性使用 SecurityContextHolder.getContext().getAuthentication() 来获取当前用户。

我在测试方法中添加了@WithMockUser,它开始工作了。我不完全知道仅独立类或仅方法测试用例如何工作,并且整体测试失败。但是添加这个注释显然让每个人都高兴。

【讨论】:

    猜你喜欢
    • 2020-03-15
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多