【问题标题】:Junit test scenario doesn't perform rollbackJunit 测试场景不执行回滚
【发布时间】:2020-11-24 19:05:42
【问题描述】:

我有以下测试,我需要证明我的事务有效并且可以回滚。这里的问题是我的 RuntimeException 是在数据输入数据库之前执行的。所以回滚不会发生。如何设置此测试?

@Test
@Rollback(true)
public void testForTransactionRollback() throws ClassNotFoundException, SQLException {

    User user = new User();
    user.setFirstName("Ivan");
    user.setLastName("Ivanov");
    user.setPhoneNumber("18000000");
    user.setEmail("mail@gmail.com");
    user.setCardNumber("4111111111111111");
    user.setDeliveryAddress("address");
    user.setComment("comment");

    String result = "";

    final ClientDAO clientDao1 = Mockito.spy(new ClientDAOImpl());

    final ClientDAOImpl clientDaoImpl = (ClientDAOImpl) clientDao1;

    Mockito.when(clientDao1.insert(user)).thenThrow(new RuntimeException());

    try {
        clientDao1.insert(user);
    } catch (final RuntimeException e) {
        System.out.println("Expected failure to trigger transaction caught");
    } finally {
        user = clientDao1.get(1L);
        if (user != null) {
            result = user.getFirstName();
        }
    }
    Assert.assertEquals("it should be equal", "", result);
}

【问题讨论】:

  • 为什么你的测试用例用Rollback(true)注解?我假设你想在你的生产代码中测试一个实际的方法,否则这个测试实际上只会证明你的测试能够执行回滚。您应该调用负责处理事务的方法,确保它失败,然后断言数据库中没有更新任何内容。

标签: java spring junit transactions


【解决方案1】:

我认为您面临的问题是由两个内部事务(一个在另一个内部)引起的:第一个在 clientDao1.insert(user) 内部,第二个在您的测试内部(前提是您用 @Transactional 注释了您的测试类或@DataJpaTest,但你没有显示)。如果RuntimeException在内部事务中抛出,是因为

Mockito.when(clientDao1.insert(user)).thenThrow(new RuntimeException());

那么这意味着您的内部 clientDao1.insert 方法无法从该异常中恢复,而外部方法(测试方法)无话可说。

这就是为什么数据永远不会被写入数据库,甚至永远不会被持久化(当然,如果你使用 hibernate 作为你的 JPA 提供程序,那么就是休眠缓存)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-21
    • 2017-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    • 2014-07-21
    • 1970-01-01
    相关资源
    最近更新 更多