### Question:
UpdateAction extends DatabaseAction<T> { @Override public void apply(final DatabaseTemplate databaseTemplate) throws Throwable { final T item = item(); item.setVersion(item.getVersion() - 1); try { databaseTemplate.update(item); } catch (final PersistenceException e) { handlePersistenceException(e); } } UpdateAction(final T item, final List<PersistenceExceptionHandler<?>> persistenceExceptionHandlers); @Override void apply(final DatabaseTemplate databaseTemplate);  }### Answer:
@Test public void shouldApplyUpdate_withDatabaseTemplate() throws Throwable { final StubItem item = new StubItem(); final Long itemVersion = randomLong(); final List<PersistenceExceptionHandler<?>> persistenceExceptionHandlers = Collections.EMPTY_LIST; final UpdateAction<StubItem> updateAction = new UpdateAction<>(item, persistenceExceptionHandlers); final DatabaseTemplate mockDatabaseTemplate = mock(DatabaseTemplate.class); item.setVersion(itemVersion); updateAction.apply(mockDatabaseTemplate); verify(mockDatabaseTemplate).update(item); assertThat(item.getVersion(), is(itemVersion - 1)); }
@Test public void shouldNotApplyUpdate_withPersistenceExceptionThrownAndNoHandlers() throws Throwable { final StubItem item = new StubItem(); final Long itemVersion = randomLong(); final List<PersistenceExceptionHandler<?>> persistenceExceptionHandlers = Collections.EMPTY_LIST; final UpdateAction<StubItem> updateAction = new UpdateAction<>(item, persistenceExceptionHandlers); final DatabaseTemplate mockDatabaseTemplate = mock(DatabaseTemplate.class); final OptimisticLockException thrownException = new OptimisticLockException("test"); item.setVersion(itemVersion); when(mockDatabaseTemplate.update(item)).thenThrow(thrownException); OptimisticLockException actualException = null; try { updateAction.apply(mockDatabaseTemplate); } catch (final OptimisticLockException e) { actualException = e; } assertNotNull(actualException); assertThat(actualException, is(thrownException)); }
@Test public void shouldNotApplyUpdateAndHandleException_withPersistenceExceptionThrownAndMatchingExceptionHandler() throws Throwable { final StubItem item = new StubItem(); final Long itemVersion = randomLong(); final PersistenceExceptionHandler<ItemConstraintViolationException> mockItemConstraintViolationExceptionHandler = (PersistenceExceptionHandler<ItemConstraintViolationException>) createMockPersistenceExceptionHandler( ItemConstraintViolationException.class, UpdateActionRuntimeException.class); final List<PersistenceExceptionHandler<?>> persistenceExceptionHandlers = Arrays .asList(mockItemConstraintViolationExceptionHandler); final UpdateAction<StubItem> updateAction = new UpdateAction<>(item, persistenceExceptionHandlers); final DatabaseTemplate mockDatabaseTemplate = mock(DatabaseTemplate.class); item.setVersion(itemVersion); when(mockDatabaseTemplate.update(item)).thenThrow(ItemConstraintViolationException.class); UpdateActionRuntimeException actualExcepion = null; try { updateAction.apply(mockDatabaseTemplate); } catch (final UpdateActionRuntimeException e) { actualExcepion = e; } verify(mockItemConstraintViolationExceptionHandler).getExceptionClass(); verify(mockItemConstraintViolationExceptionHandler).handle(any(ItemConstraintViolationException.class)); assertNotNull(actualExcepion); }
@Test public void shouldNotApplyUpdate_withPersistenceExceptionThrownAndNoMatchingExceptionHandlers() throws Throwable { final StubItem item = new StubItem(); final Long itemVersion = randomLong(); final PersistenceExceptionHandler<ItemConstraintViolationException> mockItemConstraintViolationExceptionHandler = (PersistenceExceptionHandler<ItemConstraintViolationException>) createMockPersistenceExceptionHandler( ItemConstraintViolationException.class); final List<PersistenceExceptionHandler<?>> persistenceExceptionHandlers = Arrays .asList(mockItemConstraintViolationExceptionHandler); final UpdateAction<StubItem> updateAction = new UpdateAction<>(item, persistenceExceptionHandlers); final DatabaseTemplate mockDatabaseTemplate = mock(DatabaseTemplate.class); final OptimisticLockException thrownException = new OptimisticLockException("test"); item.setVersion(itemVersion); when(mockDatabaseTemplate.update(item)).thenThrow(thrownException); OptimisticLockException actualException = null; try { updateAction.apply(mockDatabaseTemplate); } catch (final OptimisticLockException e) { actualException = e; } verify(mockItemConstraintViolationExceptionHandler).getExceptionClass(); verify(mockItemConstraintViolationExceptionHandler, never()).handle(any()); assertNotNull(actualException); assertThat(actualException, is(thrownException)); }