Announcement Announcement Module
Collapse
No announcement yet.
Web flow test not working Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Web flow test not working

    I am now devoted to learn web-flow from the available documentation, but could not still understand a couple of possibly interesting features. I have assumed that testing the flow before writing the views can save me some time, even if I only have the xml flow definition file (is that really right/possible?). So I started looking at the phonebook sample provided with the 3rd preview. Here are my questions:

    1. There seems to be a bug in class test "SearchPersonFlowTests" in phonebook sample:

    Code:
    	public void testStartFlow() {
    		startFlow();
    		assertCurrentStateEquals([b]"criteria.view"[/b]);
    	}
    	
    	public void testCriteriaView_Submit_Success() {
    		startFlow();
    		...
    		assertCurrentStateEquals([b]"results.view"[/b]);
    		...
    	}
    The states "criteria.view" and "results.view" does not exist in the corresponding xml flow definition:

    Code:
    search-flow.xml
    
    ...
    
    <webflow id="search" start-state="&#91;b&#93;displayCriteria&#91;/b&#93;">
    
    	<view-state id="&#91;b&#93;displayCriteria&#91;/b&#93;"      view="person.Search.criteria.view">
    		<setup bean="person.Search.criteria.formAction" method="setupForm"/>
    		<transition on="submit" to="&#91;b&#93;executeQuery&#91;/b&#93;">
    			<action bean="person.Search.criteria.formAction" method="bindAndValidate"/>
    			<property name="submitPressed" value="true" type="boolean"/>
    		</transition>
    	</view-state>
    	
    ...

    2. I tried with my own test,

    Code:
    ...
    
    public class PartnerFlowTests extends AbstractFlowExecutionTests &#123;
    
        public PartnerFlowTests&#40;&#41;  &#123; ...
    
        protected String flowId&#40;&#41; &#123; ...
    
        protected String&#91;&#93; getConfigLocations&#40;&#41; &#123; ...
    
        public void testStartFlow&#40;&#41; &#123;
            startFlow&#40;&#41;;
            assertCurrentStateEquals&#40;"home.view"&#41;;
        &#125;
    up to here the test runs fine, but in this method:

    Code:
        
        @SuppressWarnings&#40;"unchecked"&#41;
        public void testHomeView_Submit_Success&#40;&#41; &#123;
            startFlow&#40;&#41;;
            Map properties = new HashMap&#40;&#41;;
            properties.put&#40;"command.org.uniqueAlias", "TESTORG"&#41;;
            &#91;b&#93;ViewDescriptor view = signalEvent&#40;new Event&#40;this, "submit", properties&#41;&#41;;&#91;/b&#93;
            assertCurrentStateEquals&#40;"bindAndValidateOrg"&#41;;
    ...
    I noticed that the signalEvent did not change the state as I expected. Here is the test result:

    Code:
    junit.framework.ComparisonFailure&#58; The current state 'home.view' does not equal the expected state 'bindAndValidateOrg' &#91;b&#93;expected&#58;<bindAndValidateOrg> but was&#58;<home.view>&#91;/b&#93;
    	at junit.framework.Assert.assertEquals&#40;Assert.java&#58;81&#41;
    	at org.springframework.test.web.flow.AbstractFlowExecutionTests.assertCurrentStateEquals&#40;AbstractFlowExecutionTests.java&#58;227&#41;
    	at com.iservport.research.mvc.PartnerFlowTests.testHomeView_Submit_Success&#40;PartnerFlowTests.java&#58;42&#41;
    ...
    Here is the flow:

    Code:
    <webflow id="prtnrFlow" start-state="home.view">
    
        <view-state id="home.view" view="home">
    	<setup bean="partnerFormAction" method="setupForm"/>
            <transition on="submit" to="bindAndValidateOrg"/>
        </view-state>
    
        <action-state id="bindAndValidateOrg">
    	<action bean="partnerFormAction" 
    		method="bindAndValidate">
    		<property name="validatorMethod" 
    			value="validateOrganization"/>
    	</action>
            <transition on="success" to="findOrganization"/>
            <transition on="error" to="home.view"/>
        </action-state>
    	
    ...
    Thanks for any comment on this.

    Mauricio

  • #2
    Are you sure the bindAndValidate action is returning "success" -- methinks it's returning error, and that's why you're getting routed back to the home.view state. Turn on debug level logging and see what errors are getting generated during binding and validation. Or check the form object errors instance in the model of the returned ViewDescriptor.

    Keith

    Comment


    • #3
      Web flow test not working

      Yes, thanks Keith. There was an exception just after the setup method and that forced the flow back to the original state!

      One more question: how can I put a Mock object in place of my FormAction? Is this possible?

      Mauricio

      Comment


      • #4
        What do you want to do exactly?

        Mock out the Action interface?

        Use a MockRequestContext?

        Keith

        Comment


        • #5
          Web flow test not working

          My goal is to start the flow definition early in the process. At such stage, I may not have the FormAction tested, only the interface with the action execution methods:

          Code:
          public interface IPartnerFormAction &#123;
          
              /**
               * Required setup.
               * @see org.springframework.web.flow.action.FormAction
               */
              public Event setupForm&#40;RequestContext context&#41;
                  throws java.lang.Exception;
              
              /**
               * Required binding and validation.
               * @see org.springframework.web.flow.action.FormAction
               */
              public Event bindAndValidate&#40;RequestContext context&#41;
              	throws java.lang.Exception;
              
              /**
               * Respond to the findOrganization event.
               */
              public Event findOrganization&#40;RequestContext context&#41;;
          
          ...
          During the test:

          Code:
          ...
          
              mockFormAction.expect&#40; once&#40;&#41;&#41;
                  .method&#40;"findOrganization"&#41;
                  .with&#40; isA&#40;RequestContext.class&#41;
                  .will&#40; returnValue&#40;new Event&#40;this, "success"&#41;&#41;;
          ...
          Or further, having the FormAction coded, to test it along with the flow, mocking out only the service layer:

          Code:
          ...
          
              mockEntMgr.expect&#40; once&#40;&#41;&#41;
                  .method&#40;"findOrganizationByOwnerAndAlias"&#41;
                  .with&#40; ...&#41;
                  .will&#40; returnValue&#40;new Organization&#40;"Test"&#41;&#41;;
          ...
          The question is: how can I inject the mock objects instead of the objects themselves?

          Thanks again,

          Mauricio

          Comment


          • #6
            I don't see much value in such webflow action interfaces--it seems rare to me to ever vary implementation for what is already typically mediator code between the client and the service layer.

            I'd just rely on a stub action implementation initially (e.g returning success() for each method) and test against that. Then once your action starts needing handles to business objects (that are perhaps transactional), you can mock those out if you want. I would only do that though to support unit testing of action logic. At the flow execution level, I recommend a top down integration test that puts the flow through the ringer w/ real action implementations hooked in with real business objects--just until you get the real impls in there, just rely on simple stub implementation of your action methods as described above.

            Just a suggestion. If you really want to mock out such action interfaces, you'll need to use a MultiAction with a mock delegate property and you replace the delegate with a mock impl of your interface. That'd work nicely, actually.

            Keith

            Comment

            Working...
            X