JDBCBase { protected final void execute(ConnectionBlock connectionBlock) throws Exception { checkState(initialized); setupConnection(); checkNotNull(connection); boolean committed = false; try { connectionBlock.use(connection); connection.commit(); committed = true; } finally { if (!committed) { connection.rollback(); cleanupConnection(); } } } protected  JDBCBase(String url, String username, @Nullable String password); synchronized final void initialize(); synchronized final void teardown();  }
@Test public void shouldRollbackCommitAndCloseConnectionIfExceptionIsThrownInExecute() throws Exception { final JDBCBase.ConnectionBlock mockConnectionBlock = mock(JDBCBase.ConnectionBlock.class); doThrow(IllegalArgumentException.class).when(mockConnectionBlock).use(mockConnection); initializeJDBCTestSubclass(); assertThatExceptionIsThrown(new Callable<Void>() { @Override public Void call() throws Exception { jdbcTestSubclass.execute(mockConnectionBlock); return null; } }, IllegalArgumentException.class); InOrder inOrder = inOrder(mockConnection); inOrder.verify(mockConnection).rollback(); inOrder.verify(mockConnection).close(); }
@Test public void shouldCreateSecondConnectionAfterFirstThrowsExceptionInsideExecute() throws Exception { final JDBCBase.ConnectionBlock mockConnectionBlock = mock(JDBCBase.ConnectionBlock.class); final List<Connection> connectionsUsed = Lists.newArrayList(); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { connectionsUsed.add((Connection) invocation.getArguments()[0]); if (connectionsUsed.size() == 1) { throw new IllegalArgumentException("first invocation"); } return null; } }).when(mockConnectionBlock).use(any(Connection.class)); initializeJDBCTestSubclass(); assertThatExceptionIsThrown(new Callable<Void>() { @Override public Void call() throws Exception { jdbcTestSubclass.execute(mockConnectionBlock); return null; } }, IllegalArgumentException.class); InOrder inOrder = inOrder(mockConnection); inOrder.verify(mockConnection).rollback(); inOrder.verify(mockConnection).close(); jdbcTestSubclass.execute(mockConnectionBlock); assertThat(connectionsUsed, hasSize(2)); assertThat(connectionsUsed, contains(mockConnection, mockReplacedConnection)); }
@Test public void shouldCommitIfExecuteSucceeds() throws Exception { final JDBCBase.ConnectionBlock mockConnectionBlock = mock(JDBCBase.ConnectionBlock.class); initializeJDBCTestSubclass(); jdbcTestSubclass.execute(mockConnectionBlock); verify(mockConnection, times(2)).commit(); verify(mockConnection, times(0)).close(); }