Vlad Starostenko
Vlad Starostenko

Reputation: 131

Junit test scenario doesn't perform rollback

I have the following test where I need to show that my transaction works and can do rollback. The problem here is my RuntimeException is executed before the data is entered into the database. So rollback doesn't happen. How do I set up this test?

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

    User user = new User();
    user.setFirstName("Ivan");
    user.setLastName("Ivanov");
    user.setPhoneNumber("18000000");
    user.setEmail("[email protected]");
    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);
}

Upvotes: 2

Views: 342

Answers (1)

jwpol
jwpol

Reputation: 1475

I think the problem you're facing is caused by two inner transactions (one inside the other): first one is inside clientDao1.insert(user) and a second one inside your test (providing that you annotated your test class with @Transactional or @DataJpaTest, but you've not shown that). If RuntimeException is thrown within inner transaction, which is the case because of

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

then it means your inner clientDao1.insert method cannot recover from that exception and the outer method (test one) has nothing to say.

That's why data will NEVER be written to the database or even persisted (hibernate caching, of course if you use hibernate as your JPA provider).

Upvotes: 1

Related Questions