Announcement Announcement Module
Collapse
No announcement yet.
Testing a flow with subflow doesn't work Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Testing a flow with subflow doesn't work

    I'm trying to use JUnit and AbstractXmlFlowExecutionTests to unit test a flow.

    I've read the webflow doco on testing.

    The flow I'm testing calls a subflow, and that's where I get the error :

    Caused by: org.springframework.webflow.definition.registry.No SuchFlowDefinitionException: No flow definition 'select-scenario' found, which occurs on line 97 of org.springframework.webflow.engine.SubflowState when an attempt is made to locate the 'select-scenario' flow.

    Line 97 -> Flow subflow = (Flow) this.subflow.getValue(context);

    My test is as follows:

    Code:
    setCurrentState("newOrExisting");
    		
    getFlowDefinitionRegistry().registerFlowDefinition(createMockSelectScenarioSubflow());
    		
    MutableAttributeMap input = new LocalAttributeMap();
    input.put("reserveManagerId", "8");
    MockExternalContext context = new MockExternalContext();
    		
    startFlow(input, context);
    where createMockSelectScenarioSubflow() is based on the Spring webflow doco here http://static.springframework.org/sp...l/ch14s07.html, except I've changed "booking" (as per the doc) to "select-scenario"

    The above code works to some extent. The flow starts, and I get an error where the top level flow being tested tries to go into the mocked subflow -- which can't be found even though I'd registered it as per the Spring webflow doco.

    It seems like the 'select-scenario' flow isn't registered with the flowDefinitionLocator, but I'm not sure whether I'm doing the right thing, or somehow need to get a reference to a flowDefinitionLocator to do some additional registration of the select-scenario flow.

    See the getValue() method in org.springframework.webflow.engine.builder.model.S ubflowExpression

    getValue, line 35: return flowDefinitionLocator.getFlowDefinition(subflowId) ;

    is returning null.

    Any help much appreciated,

  • #2
    Is there a reason you're calling startFlow instead of resumeFlow? When you call setCurrentState you are already starting the flow implicitly. Take a close look at MainFlowExecutionTests.testBookHotel() from booking faces sample.

    Keith

    Comment


    • #3
      Am calling startFlow out of naievety more than anything else, and getting a different error below now when I replace the call to startFlow with a call to resumeFlow.

      The first thing that the top level flow does (which is what I want to test) is call the mocked subflow.

      The web flow states are:

      decision state -> subflow (select-scenario) -> decision state -> action state -> view state.

      There is no view state reached until several decision, subflow, and action states have occurred. Not sure if this is relevant.

      Help.

      org.springframework.webflow.execution.FlowExecutio nException: Exception thrown in state 'newOrExisting' of flow 'annual-return-flow'
      at org.springframework.webflow.engine.impl.FlowExecut ionImpl.wrap(FlowExecutionImpl.java:567)
      at org.springframework.webflow.engine.impl.FlowExecut ionImpl.resume(FlowExecutionImpl.java:266)
      at org.springframework.webflow.test.execution.Abstrac tFlowExecutionTests.resumeFlow(AbstractFlowExecuti onTests.java:138)
      at
      ...
      Caused by: java.lang.IllegalStateException: You can only resume paused view states, and state [DecisionState@a50da4 id = 'newOrExisting', flow = 'annual-return-flow', entryActionList = list[[empty]], exceptionHandlerSet = list[[empty]], transitions = list[[Transition@229ed4 on = id == null, to = selectScenario], [Transition@e9a7c2 on = *, to = resolveContext]], exitActionList = list[[empty]]] is not a view state - programmer error
      at org.springframework.webflow.engine.Flow.getCurrent ViewState(Flow.java:645)
      at org.springframework.webflow.engine.Flow.resume(Flo w.java:545)
      at org.springframework.webflow.engine.impl.FlowExecut ionImpl.resume(FlowExecutionImpl.java:262)
      ... 20 more
      Last edited by gmatthews; Mar 18th, 2009, 10:06 PM. Reason: add list of flow state types

      Comment


      • #4
        Don't call setCurrentState at all and use startFlow.

        Keith

        Comment


        • #5
          Hi Keith,

          Still doesn't work.

          1. I get an NPE if I try to register the mock subflow before calling startFlow.
          2. If I swap it around, and call startFlow before registering the subflow then I get an error that the subflow can't be found.

          I'm guessing I need to register the mock subflow before calling startFlow -- because startFlow is going to try to proceed to either a view-state or finish-state before it pauses/ends respectively. Is this right?

          This method in AbstractExternalizedFlowExecutionTests throws a NPE when I try to register a mock subflow, before startFlow has been called.

          protected FlowDefinitionRegistry getFlowDefinitionRegistry() {
          return (FlowDefinitionRegistry) flowBuilderContext.getFlowDefinitionLocator();
          }

          Any ideas? I guess I can debug the code to see what I'm doing wrong. I suspect I need to override some method somewhere or something but not sure what.

          Comment


          • #6
            Yeah, interesting.

            You'll need to override protected void configureFlowBuilderContext(MockFlowBuilderContext builderContext)

            ... and register your mock subflow in there.

            The downside of this is you probably don't want that mock registered for other test cases. Can you open an improvemenet JIRA on this?

            Keith

            Comment


            • #7
              http://jira.springframework.org/browse/SWF-1079

              I hope I've captured the essence of what you thought could be improved...

              I don't have a problem creating multiple JUnit classes if that's the workaround for overriding configureFlowBuilderContext and calling builderContext.registerSubflow within that.

              My issue was just working out how to drive the testing API.

              Regards,

              Comment

              Working...
              X