@Test
  public final void shouldSaveButNotSetJustInvalidateOwnerEntity() {
    // given
    given(owner.isValid()).willReturn(true);
    given(ownerDD.save(owner)).willReturn(savedOwner);
    given(savedOwner.isValid()).willReturn(false);

    final Map<String, ErrorMessage> fieldErrorsMap = Maps.newHashMap();
    final ErrorMessage fieldErrorMessage = buildErrorMessage(FIELD_1_MESSAGE_1);
    fieldErrorsMap.put(FIELD_1_NAME, fieldErrorMessage);
    given(savedOwner.getErrors()).willReturn(fieldErrorsMap);

    final List<ErrorMessage> globalErrors = Lists.newArrayList();
    final ErrorMessage globalErrorMessage = buildErrorMessage(GLOBAL_MESSAGE_1);
    globalErrors.add(globalErrorMessage);
    given(savedOwner.getGlobalErrors()).willReturn(globalErrors);

    // when
    stateChangeContext.setOwner(owner);

    // then
    verify(ownerDD).save(owner);
    verify(stateChangeEntity, never()).setField(describer.getOwnerFieldName(), owner);
    verify(stateChangeEntity, never()).setField(describer.getOwnerFieldName(), savedOwner);
    verify(messageService)
        .addValidationError(
            stateChangeContext, FIELD_1_NAME, FIELD_1_MESSAGE_1, EMPTY_STRING_ARRAY);
    verify(messageService)
        .addValidationError(stateChangeContext, null, GLOBAL_MESSAGE_1, EMPTY_STRING_ARRAY);
    verify(stateChangeEntity)
        .setField(describer.getStatusFieldName(), StateChangeStatus.FAILURE.getStringValue());
  }
  @Test
  public final void shouldSaveAndSetOwnerEntity() {
    // given
    given(owner.isValid()).willReturn(true);
    given(savedOwner.isValid()).willReturn(true);
    given(ownerDD.save(owner)).willReturn(savedOwner);

    // when
    stateChangeContext.setOwner(owner);

    // then
    verify(ownerDD).save(owner);
    verify(stateChangeEntity, never()).setField(describer.getOwnerFieldName(), owner);
    verify(stateChangeEntity).setField(describer.getOwnerFieldName(), savedOwner);
    verify(messageService, never())
        .addValidationError(
            Mockito.eq(stateChangeContext),
            Mockito.anyString(),
            Mockito.anyString(),
            Mockito.any(String[].class));
    verify(messageService, never())
        .addValidationError(
            Mockito.eq(stateChangeContext),
            Mockito.eq((String) null),
            Mockito.anyString(),
            Mockito.any(String[].class));
    verify(stateChangeEntity, never())
        .setField(describer.getStatusFieldName(), StateChangeStatus.FAILURE.getStringValue());
  }
  @Test
  public final void
      shouldMarkEntityAsInvalidAndSetStateToFailureIfStateChangeEntityIsInvalidAfterSave() {
    // given
    final Entity savedStateChangeEntity = mock(Entity.class);
    given(stateChangeEntity.isValid()).willReturn(true);
    given(savedStateChangeEntity.isValid()).willReturn(true, false);
    given(stateChangeDD.save(stateChangeEntity)).willReturn(savedStateChangeEntity);

    final Map<String, ErrorMessage> fieldErrorsMap = Maps.newHashMap();
    final ErrorMessage fieldErrorMessage = buildErrorMessage(FIELD_1_MESSAGE_1);
    fieldErrorsMap.put(FIELD_1_NAME, fieldErrorMessage);
    given(savedStateChangeEntity.getErrors()).willReturn(fieldErrorsMap);

    final List<ErrorMessage> globalErrors = Lists.newArrayList();
    final ErrorMessage globalErrorMessage = buildErrorMessage(GLOBAL_MESSAGE_1);
    globalErrors.add(globalErrorMessage);
    given(savedStateChangeEntity.getGlobalErrors()).willReturn(globalErrors);

    // when
    stateChangeContext.save();

    // then
    verify(messageService)
        .addValidationError(
            stateChangeContext, FIELD_1_NAME, FIELD_1_MESSAGE_1, EMPTY_STRING_ARRAY);
    verify(messageService)
        .addValidationError(stateChangeContext, null, GLOBAL_MESSAGE_1, EMPTY_STRING_ARRAY);
    verify(stateChangeEntity).setField(describer.getStatusFieldName(), FAILURE.getStringValue());
  }
 @Before
 public final void init() {
   MockitoAnnotations.initMocks(this);
   describer = new MockStateChangeDescriber(stateChangeDD);
   stubStateChangeEntity(describer);
   stubOwner();
   stubBelongsToField(stateChangeEntity, describer.getOwnerFieldName(), owner);
   stateChangeContext = new StateChangeContextImpl(stateChangeEntity, describer, messageService);
 }
  @Test
  public final void shouldMarkEntityAsFailureAndRethrowExceptionIfOwnerValidatorThrowsException() {
    // given
    given(ownerDD.save(owner)).willThrow(new RuntimeException());

    try {
      // when
      stateChangeContext.setOwner(owner);
    } catch (StateChangeException e) {
      // then
      verify(stateChangeEntity).setField(describer.getStatusFieldName(), FAILURE.getStringValue());
    }
  }
  @Test
  public final void shouldSave() {
    // when
    stateChangeContext.save();

    // then
    verify(stateChangeDD, atLeastOnce()).save(stateChangeEntity);
    verify(messageService, never())
        .addValidationError(
            Mockito.eq(stateChangeContext),
            Mockito.anyString(),
            Mockito.anyString(),
            Mockito.any(String[].class));
    verify(messageService, never())
        .addValidationError(
            Mockito.eq(stateChangeContext),
            Mockito.eq((String) null),
            Mockito.anyString(),
            Mockito.any(String[].class));
    verify(stateChangeEntity, never())
        .setField(describer.getStatusFieldName(), FAILURE.getStringValue());
  }
  @Test
  public final void
      shouldMarkExistingDatabaseEntityAsInvalidIfConstructorGetInvalidStateChangeEntity() {
    // given
    final Entity existingStateChangeEntity = mock(Entity.class);
    given(stateChangeEntity.isValid()).willReturn(false);
    given(stateChangeEntity.getId()).willReturn(1L);
    given(stateChangeDD.get(Mockito.any(Long.class))).willReturn(existingStateChangeEntity);
    given(existingStateChangeEntity.isValid()).willReturn(true);

    final Map<String, ErrorMessage> fieldErrorsMap = Maps.newHashMap();
    final ErrorMessage fieldErrorMessage = buildErrorMessage(FIELD_1_MESSAGE_1);
    fieldErrorsMap.put(FIELD_1_NAME, fieldErrorMessage);
    given(stateChangeEntity.getErrors()).willReturn(fieldErrorsMap);

    final List<ErrorMessage> globalErrors = Lists.newArrayList();
    final ErrorMessage globalErrorMessage = buildErrorMessage(GLOBAL_MESSAGE_1);
    globalErrors.add(globalErrorMessage);
    given(stateChangeEntity.getGlobalErrors()).willReturn(globalErrors);

    // when
    new StateChangeContextImpl(stateChangeEntity, describer, messageService);

    // then
    verify(messageService)
        .addValidationError(
            Mockito.any(StateChangeContext.class),
            Mockito.eq(FIELD_1_NAME),
            Mockito.eq(FIELD_1_MESSAGE_1));
    verify(messageService)
        .addValidationError(
            Mockito.any(StateChangeContext.class),
            Mockito.eq((String) null),
            Mockito.eq(GLOBAL_MESSAGE_1));
    verify(existingStateChangeEntity)
        .setField(describer.getStatusFieldName(), FAILURE.getStringValue());
  }