protected ScenarioResult fillResult(FactMappingValue expectedResult,
                                        Supplier<ValueWrapper<?>> resultSupplier,
                                        ExpressionEvaluator expressionEvaluator) {
        ValueWrapper<?> resultValue = resultSupplier.get();

        if (resultValue.isValid()) {
            // result is satisfied so clean up previous error state
            expectedResult.resetStatus();
        } else if (resultValue.getErrorMessage().isPresent()) {
            // propagate error message
            expectedResult.setExceptionMessage(resultValue.getErrorMessage().get());
        } else if (resultValue.getCollectionPathToValue() != null) {
            expectedResult.setCollectionPathToValue(resultValue.getCollectionPathToValue());
            expectedResult.setErrorValue(resultValue.getValue());
        } else {
            try {
                // set actual as proposed value
                expectedResult.setErrorValue(expressionEvaluator.fromObjectToExpression(resultValue.getValue()));
            } catch (Exception e) {
                // otherwise generic error message
                expectedResult.setExceptionMessage(e.getMessage());
            }
        }

        return new ScenarioResult(expectedResult, resultValue.getValue()).setResult(resultValue.isValid());
    }
@Test
    public void fillResult() {
        FactIdentifier factIdentifier = FactIdentifier.create("MyInstance", String.class.getCanonicalName());
        ExpressionIdentifier expressionIdentifier = ExpressionIdentifier.create("MyProperty", FactMappingType.GIVEN);
        FactMappingValue expectedResultSpy = spy(new FactMappingValue(factIdentifier, expressionIdentifier, VALUE));
        AtomicReference<ValueWrapper<Object>> resultWrapperAtomicReference = new AtomicReference<>();
        Supplier<ValueWrapper<?>> resultWrapperSupplier = resultWrapperAtomicReference::get;
        ExpressionEvaluator expressionEvaluator = new BaseExpressionEvaluator(AbstractRunnerHelper.class.getClassLoader());

        // Success
        resultWrapperAtomicReference.set(ValueWrapper.of(VALUE));
        assertThat(abstractRunnerHelper.fillResult(expectedResultSpy, resultWrapperSupplier, expressionEvaluator).getResult()).isTrue();
        verify(expectedResultSpy, times(1)).resetStatus();

        reset(expectedResultSpy);

        // Fail with expected value
        resultWrapperAtomicReference.set(ValueWrapper.errorWithValidValue(VALUE, "value1"));
        assertThat(abstractRunnerHelper.fillResult(expectedResultSpy, resultWrapperSupplier, expressionEvaluator).getResult()).isFalse();
        verify(expectedResultSpy, times(1)).setErrorValue(VALUE);

        reset(expectedResultSpy);

        // Fail with exception while reverting actual value
        resultWrapperAtomicReference.set(ValueWrapper.errorWithValidValue(VALUE, "value1"));
        ExpressionEvaluator expressionEvaluatorMock = mock(ExpressionEvaluator.class);
        when(expressionEvaluatorMock.fromObjectToExpression(any())).thenThrow(new IllegalArgumentException("Error"));
        assertThat(abstractRunnerHelper.fillResult(expectedResultSpy, resultWrapperSupplier, expressionEvaluatorMock).getResult()).isFalse();
        verify(expectedResultSpy, times(1)).setExceptionMessage("Error");

        reset(expectedResultSpy);

        // Fail in collection case
        List<String> pathToValue = List.of("field1", "fields2");
        resultWrapperAtomicReference.set(ValueWrapper.errorWithCollectionPathToValue(VALUE, pathToValue));
        assertThat(abstractRunnerHelper.fillResult(expectedResultSpy, resultWrapperSupplier, expressionEvaluator).getResult()).isFalse();
        verify(expectedResultSpy, times(1)).setCollectionPathToValue(pathToValue);
        verify(expectedResultSpy, times(1)).setErrorValue(VALUE);

        // Fail with exception
        resultWrapperAtomicReference.set(ValueWrapper.errorWithMessage("detailedError"));
        assertThat(abstractRunnerHelper.fillResult(expectedResultSpy, resultWrapperSupplier, expressionEvaluator).getResult()).isFalse();
        verify(expectedResultSpy, times(1)).setExceptionMessage("detailedError");
    }