### Question:
TransactionRepresentationCommitProcess implements TransactionCommitProcess { @Override public long commit( TransactionToApply batch, CommitEvent commitEvent, TransactionApplicationMode mode ) throws TransactionFailureException { long lastTxId = appendToLog( batch, commitEvent ); try { applyToStore( batch, commitEvent, mode ); return lastTxId; } finally { close( batch ); } } TransactionRepresentationCommitProcess( TransactionAppender appender, StorageEngine storageEngine ); @Override long commit( TransactionToApply batch, CommitEvent commitEvent,
            TransactionApplicationMode mode );  }### Answer:
@Test public void shouldFailWithProperMessageOnAppendException() throws Exception { TransactionAppender appender = mock( TransactionAppender.class ); IOException rootCause = new IOException( "Mock exception" ); doThrow( new IOException( rootCause ) ).when( appender ).append( any( TransactionToApply.class ), any( LogAppendEvent.class ) ); StorageEngine storageEngine = mock( StorageEngine.class ); TransactionCommitProcess commitProcess = new TransactionRepresentationCommitProcess( appender, storageEngine ); try { commitProcess.commit( mockedTransaction(), commitEvent, INTERNAL ); fail( "Should have failed, something is wrong with the mocking in this test" ); } catch ( TransactionFailureException e ) { assertThat( e.getMessage(), containsString( "Could not append transaction representation to log" ) ); assertTrue( contains( e, rootCause.getMessage(), rootCause.getClass() ) ); } }
@Test public void shouldCloseTransactionRegardlessOfWhetherOrNotItAppliedCorrectly() throws Exception { TransactionIdStore transactionIdStore = mock( TransactionIdStore.class ); TransactionAppender appender = new TestableTransactionAppender( transactionIdStore ); long txId = 11; when( transactionIdStore.nextCommittingTransactionId() ).thenReturn( txId ); IOException rootCause = new IOException( "Mock exception" ); StorageEngine storageEngine = mock( StorageEngine.class ); doThrow( new IOException( rootCause ) ).when( storageEngine ).apply( any( TransactionToApply.class ), any( TransactionApplicationMode.class ) ); TransactionCommitProcess commitProcess = new TransactionRepresentationCommitProcess( appender, storageEngine ); TransactionToApply transaction = mockedTransaction(); try { commitProcess.commit( transaction, commitEvent, INTERNAL ); } catch ( TransactionFailureException e ) { assertThat( e.getMessage(), containsString( "Could not apply the transaction to the store" ) ); assertTrue( contains( e, rootCause.getMessage(), rootCause.getClass() ) ); } verify( transactionIdStore, times( 1 ) ).transactionClosed( eq( txId ), anyLong(), anyLong() ); }
@Test public void shouldSuccessfullyCommitTransactionWithNoCommands() throws Exception { long txId = 11; long commitTimestamp = System.currentTimeMillis(); TransactionIdStore transactionIdStore = mock( TransactionIdStore.class ); TransactionAppender appender = new TestableTransactionAppender( transactionIdStore ); when( transactionIdStore.nextCommittingTransactionId() ).thenReturn( txId ); StorageEngine storageEngine = mock( StorageEngine.class ); TransactionCommitProcess commitProcess = new TransactionRepresentationCommitProcess( appender, storageEngine ); PhysicalTransactionRepresentation noCommandTx = new PhysicalTransactionRepresentation( Collections.emptyList() ); noCommandTx.setHeader( new byte[0], -1, -1, -1, -1, -1, -1 ); commitProcess.commit( new TransactionToApply( noCommandTx ), commitEvent, INTERNAL ); verify( transactionIdStore ).transactionCommitted( txId, FakeCommitment.CHECKSUM, FakeCommitment.TIMESTAMP ); }