14.7. Mocking a subflow

To test calling a subflow, register a mock implementation of the subflow that asserts input was passed in correctly and returns the correct outcome for your test scenario.

public void testBookHotel() {
    
    setCurrentState("reviewHotel");

    Hotel hotel = new Hotel();
    hotel.setId(1L);
    hotel.setName("Jameson Inn");
    getFlowScope().put("hotel", hotel);

    getFlowDefinitionRegistry().registerFlowDefinition(createMockBookingSubflow());

    MockExternalContext context = new MockExternalContext();
    context.setEventId("book");
    resumeFlow(context);

    // verify flow ends on 'bookingConfirmed'
    assertFlowExecutionEnded();
    assertFlowExecutionOutcomeEquals("finish");
}

public Flow createMockBookingSubflow() {
    Flow mockBookingFlow = new Flow("booking");
    mockBookingFlow.setInputMapper(new Mapper() {
        public MappingResults map(Object source, Object target) {
            // assert that 1L was passed in as input
            assertEquals(1L, ((AttributeMap) source).get("hotelId"));
            return null;
        }
    });
    // immediately return the bookingConfirmed outcome so the caller can respond
    new EndState(mockBookingFlow, "bookingConfirmed");
    return mockBookingFlow;
}