org.springframework.webflow.test.execution
Class AbstractFlowExecutionTests

java.lang.Object
  extended by junit.framework.Assert
      extended by junit.framework.TestCase
          extended by org.springframework.webflow.test.execution.AbstractFlowExecutionTests
All Implemented Interfaces:
junit.framework.Test
Direct Known Subclasses:
AbstractExternalizedFlowExecutionTests

public abstract class AbstractFlowExecutionTests
extends junit.framework.TestCase

Base class for integration tests that verify a flow executes as expected. Flow execution tests captured by subclasses should test that a flow responds to all supported transition criteria correctly, transitioning to the correct states and producing the expected results on the occurence of possible external (user) events.

More specifically, a typical flow execution test case will test:

A flow execution test can effectively automate and validate the orchestration required to drive an end-to-end business task that spans several steps involving the user to complete. Such tests are a good way to test your system top-down starting at the web-tier and pushing through all the way to the DB without having to deploy to a servlet or portlet container. In addition, they can be used to effectively test a flow's execution (the web layer) standalone, typically with a mock service layer. Both styles of testing are valuable and supported.

Author:
Keith Donald

Constructor Summary
AbstractFlowExecutionTests()
          Constructs a default flow execution test.
AbstractFlowExecutionTests(java.lang.String name)
          Constructs a flow execution test with given name.
 
Method Summary
protected  ApplicationView applicationView(ViewSelection viewSelection)
          Assert that the returned view selection is an instance of ApplicationView.
protected  void assertActiveFlowEquals(java.lang.String expectedActiveFlowId)
          Assert that the active flow session is for the flow with the provided id.
protected  void assertCurrentStateEquals(java.lang.String expectedCurrentStateId)
          Assert that the current state of the flow execution equals the provided state id.
protected  void assertFlowExecutionActive()
          Assert that the entire flow execution is active; that is, it has not ended and has been started.
protected  void assertFlowExecutionEnded()
          Assert that the entire flow execution has ended; that is, it is no longer active.
protected  void assertModelAttributeCollectionSize(int expectedSize, java.lang.String attributeName, ApplicationView viewSelection)
          Assert that the selected view contains the specified collection model attribute with the provided expected size.
protected  void assertModelAttributeEquals(java.lang.Object expectedValue, java.lang.String attributeName, ApplicationView viewSelection)
          Assert that the selected view contains the specified model attribute with the provided expected value.
protected  void assertModelAttributeNotNull(java.lang.String attributeName, ApplicationView viewSelection)
          Assert that the selected view contains the specified model attribute.
protected  void assertModelAttributeNull(java.lang.String attributeName, ApplicationView viewSelection)
          Assert that the selected view does not contain the specified model attribute.
protected  void assertViewNameEquals(java.lang.String expectedViewName, ApplicationView viewSelection)
          Assert that the view name equals the provided value.
protected  ExternalContext createExternalContext(ParameterMap requestParameters)
          Creates an ExternalContext instance.
protected  FlowExecutionFactory createFlowExecutionFactory()
          Factory method to create the flow execution factory.
protected  java.lang.Object evaluateModelAttributeExpression(java.lang.String attributeName, java.util.Map model)
          Evaluates a model attribute expression.
protected  ExternalRedirect externalRedirect(ViewSelection viewSelection)
          Assert that the returned view selection is an instance of ExternalRedirect.
protected  FlowDefinitionRedirect flowDefinitionRedirect(ViewSelection viewSelection)
          Assert that the returned view selection is an instance of FlowDefinitionRedirect.
protected  FlowExecutionRedirect flowExecutionRedirect(ViewSelection viewSelection)
          Assert that the returned view selection is an instance of FlowExecutionRedirect.
protected  java.lang.Object getConversationAttribute(java.lang.String attributeName)
          Returns the attribute in conversation scope.
protected  java.lang.Object getFlashAttribute(java.lang.String attributeName)
          Returns the attribute in flash scope.
protected  java.lang.Object getFlowAttribute(java.lang.String attributeName)
          Returns the attribute in flow scope.
protected abstract  FlowDefinition getFlowDefinition()
          Returns the flow definition to be tested.
protected  FlowExecution getFlowExecution()
          Returns the flow execution being tested.
protected  FlowExecutionFactory getFlowExecutionFactory()
          Gets the factory that will create the flow execution to test.
protected  java.lang.Object getRequiredConversationAttribute(java.lang.String attributeName)
          Returns the required attribute in conversation scope; asserts the attribute is present.
protected  java.lang.Object getRequiredConversationAttribute(java.lang.String attributeName, java.lang.Class requiredType)
          Returns the required attribute in conversation scope; asserts the attribute is present and of the required type.
protected  java.lang.Object getRequiredFlashAttribute(java.lang.String attributeName)
          Returns the required attribute in flash scope; asserts the attribute is present.
protected  java.lang.Object getRequiredFlashAttribute(java.lang.String attributeName, java.lang.Class requiredType)
          Returns the required attribute in flash scope; asserts the attribute is present and of the correct type.
protected  java.lang.Object getRequiredFlowAttribute(java.lang.String attributeName)
          Returns the required attribute in flow scope; asserts the attribute is present.
protected  java.lang.Object getRequiredFlowAttribute(java.lang.String attributeName, java.lang.Class requiredType)
          Returns the required attribute in flow scope; asserts the attribute is present and of the correct type.
protected  void nullView(ViewSelection viewSelection)
          Assert that the returned view selection is the ViewSelection.NULL_VIEW.
protected  ViewSelection refresh()
          Refresh the flow execution being tested, asking the current view state to make a "refresh" view selection.
protected  ViewSelection refresh(ExternalContext context)
          Refresh the flow execution being tested, asking the current view state state to make a "refresh" view selection.
 void setExpressionParser(org.springframework.binding.expression.ExpressionParser expressionParser)
          Set the expression parser responsible for parsing expression strings into evaluatable expression objects.
protected  ViewSelection signalEvent(java.lang.String eventId)
          Signal an occurence of an event in the current state of the flow execution being tested.
protected  ViewSelection signalEvent(java.lang.String eventId, ExternalContext context)
          Signal an occurence of an event in the current state of the flow execution being tested.
protected  ViewSelection signalEvent(java.lang.String eventId, ParameterMap requestParameters)
          Signal an occurence of an event in the current state of the flow execution being tested.
protected  ViewSelection startFlow()
          Start the flow execution to be tested.
protected  ViewSelection startFlow(MutableAttributeMap input)
          Start the flow execution to be tested.
protected  ViewSelection startFlow(MutableAttributeMap input, ExternalContext context)
          Start the flow execution to be tested.
protected  void updateFlowExecution(FlowExecution flowExecution)
          Directly update the flow execution used by the test by setting it to given flow execution.
 
Methods inherited from class junit.framework.TestCase
countTestCases, createResult, getName, run, run, runBare, runTest, setName, setUp, tearDown, toString
 
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail, failNotEquals, failNotSame, failSame
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

AbstractFlowExecutionTests

public AbstractFlowExecutionTests()
Constructs a default flow execution test.

See Also:
TestCase.setName(String)

AbstractFlowExecutionTests

public AbstractFlowExecutionTests(java.lang.String name)
Constructs a flow execution test with given name.

Parameters:
name - the name of the test
Since:
1.0.2
Method Detail

setExpressionParser

public void setExpressionParser(org.springframework.binding.expression.ExpressionParser expressionParser)
Set the expression parser responsible for parsing expression strings into evaluatable expression objects.


getFlowExecutionFactory

protected FlowExecutionFactory getFlowExecutionFactory()
Gets the factory that will create the flow execution to test. This method will create the factory if it is not already set.

Returns:
the flow execution factory
See Also:
createFlowExecutionFactory()

createExternalContext

protected ExternalContext createExternalContext(ParameterMap requestParameters)
Creates an ExternalContext instance. Defaults to using MockExternalContext. Subclasses can override if they which to use another external context implementation.

Parameters:
requestParameters - request parameters to put into the external context (optional)
Returns:
a new ExternalContext instance

startFlow

protected ViewSelection startFlow()
                           throws FlowExecutionException
Start the flow execution to be tested.

Convenience operation that starts the execution with:

Returns:
the view selection made as a result of starting the flow (returned when the first interactive state (a view state or end state) is entered)
Throws:
FlowExecutionException - if an exception was thrown while starting the flow execution

startFlow

protected ViewSelection startFlow(MutableAttributeMap input)
                           throws FlowExecutionException
Start the flow execution to be tested.

Convenience operation that starts the execution with:

Parameters:
input - the flow execution input attributes eligible for mapping by the root flow
Returns:
the view selection made as a result of starting the flow (returned when the first interactive state (a view state or end state) is entered)
Throws:
FlowExecutionException - if an exception was thrown while starting the flow execution

startFlow

protected ViewSelection startFlow(MutableAttributeMap input,
                                  ExternalContext context)
                           throws FlowExecutionException
Start the flow execution to be tested.

This is the most flexible of the start methods. It allows you to specify:

  1. a map of input attributes to pass to the flow execution, eligible for mapping by the root flow definition
  2. an external context that provides the flow execution being tested access to the calling environment for this request

Parameters:
input - the flow execution input attributes eligible for mapping by the root flow
context - the external context providing information about the caller's environment, used by the flow execution during the start operation
Returns:
the view selection made as a result of starting the flow (returned when the first interactive state (a view state or end state) is entered)
Throws:
FlowExecutionException - if an exception was thrown while starting the flow execution

signalEvent

protected ViewSelection signalEvent(java.lang.String eventId)
                             throws FlowExecutionException
Signal an occurence of an event in the current state of the flow execution being tested.

Parameters:
eventId - the event that occured
Throws:
FlowExecutionException - if an exception was thrown within a state of the resumed flow execution during event processing

signalEvent

protected ViewSelection signalEvent(java.lang.String eventId,
                                    ParameterMap requestParameters)
                             throws FlowExecutionException
Signal an occurence of an event in the current state of the flow execution being tested.

Parameters:
eventId - the event that occured
requestParameters - request parameters needed by the flow execution to complete event processing
Throws:
FlowExecutionException - if an exception was thrown within a state of the resumed flow execution during event processing

signalEvent

protected ViewSelection signalEvent(java.lang.String eventId,
                                    ExternalContext context)
                             throws FlowExecutionException
Signal an occurence of an event in the current state of the flow execution being tested.

Note: signaling an event will cause state transitions to occur in a chain until control is returned to the caller. Control is returned once an "interactive" state type is entered: either a view state when the flow is paused or an end state when the flow terminates. Action states are executed without returning control, as their result always triggers another state transition, executed internally. Action states can also be executed in a chain like fashion (e.g. action state 1 (result), action state 2 (result), action state 3 (result), view state ).

If you wish to verify expected behavior on each state transition (and not just when the view state triggers return of control back to the client), you have a few options:

First, you may implement standalone unit tests for your Action implementations. There you can verify that an Action executes its logic properly in isolation. When you do this, you may mock or stub out services the Action implementation needs that are expensive to initialize. You can also verify there that the action puts everything in the flow or request scope it was expected to (to meet its contract with the view it is prepping for display, for example).

Second, you can attach one or more FlowExecutionListeners to the flow execution at start time within your test code, which will allow you to receive a callback on each state transition (among other points). It is recommended you extend FlowExecutionListenerAdapter and only override the callback methods you are interested in.

Parameters:
eventId - the event that occured
context - the external context providing information about the caller's environment, used by the flow execution during the signal event operation
Returns:
the view selection that was made, returned once control is returned to the client (occurs when the flow enters a view state, or an end state)
Throws:
FlowExecutionException - if an exception was thrown within a state of the resumed flow execution during event processing

refresh

protected ViewSelection refresh()
                         throws FlowExecutionException
Refresh the flow execution being tested, asking the current view state to make a "refresh" view selection. This is idempotent operation that may be safely called on an active but currently paused execution. Used to simulate a browser flow execution redirect.

Returns:
the current view selection for this flow execution
Throws:
FlowExecutionException - if an exception was thrown during refresh

refresh

protected ViewSelection refresh(ExternalContext context)
                         throws FlowExecutionException
Refresh the flow execution being tested, asking the current view state state to make a "refresh" view selection. This is idempotent operation that may be safely called on an active but currently paused execution. Used to simulate a browser flow execution redirect.

Parameters:
context - the external context providing information about the caller's environment, used by the flow execution during the refresh operation
Returns:
the current view selection for this flow execution
Throws:
FlowExecutionException - if an exception was thrown during refresh

getFlowExecution

protected FlowExecution getFlowExecution()
                                  throws java.lang.IllegalStateException
Returns the flow execution being tested.

Returns:
the flow execution
Throws:
java.lang.IllegalStateException - the execution has not been started

getConversationAttribute

protected java.lang.Object getConversationAttribute(java.lang.String attributeName)
Returns the attribute in conversation scope. Conversation-scoped attributes are shared by all flow sessions.

Parameters:
attributeName - the name of the attribute
Returns:
the attribute value

getRequiredConversationAttribute

protected java.lang.Object getRequiredConversationAttribute(java.lang.String attributeName)
                                                     throws java.lang.IllegalStateException
Returns the required attribute in conversation scope; asserts the attribute is present. Conversation-scoped attributes are shared by all flow sessions.

Parameters:
attributeName - the name of the attribute
Returns:
the attribute value
Throws:
java.lang.IllegalStateException - if the attribute was not present

getRequiredConversationAttribute

protected java.lang.Object getRequiredConversationAttribute(java.lang.String attributeName,
                                                            java.lang.Class requiredType)
                                                     throws java.lang.IllegalStateException
Returns the required attribute in conversation scope; asserts the attribute is present and of the required type. Conversation-scoped attributes are shared by all flow sessions.

Parameters:
attributeName - the name of the attribute
Returns:
the attribute value
Throws:
java.lang.IllegalStateException - if the attribute was not present or not of the required type

getFlowAttribute

protected java.lang.Object getFlowAttribute(java.lang.String attributeName)
Returns the attribute in flow scope. Flow-scoped attributes are local to the active flow session.

Parameters:
attributeName - the name of the attribute
Returns:
the attribute value

getRequiredFlowAttribute

protected java.lang.Object getRequiredFlowAttribute(java.lang.String attributeName)
                                             throws java.lang.IllegalStateException
Returns the required attribute in flow scope; asserts the attribute is present. Flow-scoped attributes are local to the active flow session.

Parameters:
attributeName - the name of the attribute
Returns:
the attribute value
Throws:
java.lang.IllegalStateException - if the attribute was not present

getRequiredFlowAttribute

protected java.lang.Object getRequiredFlowAttribute(java.lang.String attributeName,
                                                    java.lang.Class requiredType)
                                             throws java.lang.IllegalStateException
Returns the required attribute in flow scope; asserts the attribute is present and of the correct type. Flow-scoped attributes are local to the active flow session.

Parameters:
attributeName - the name of the attribute
Returns:
the attribute value
Throws:
java.lang.IllegalStateException - if the attribute was not present or was of the wrong type

getFlashAttribute

protected java.lang.Object getFlashAttribute(java.lang.String attributeName)
Returns the attribute in flash scope. Flash-scoped attributes are local to the active flow session and cleared on the next user event.

Parameters:
attributeName - the name of the attribute
Returns:
the attribute value
Since:
1.0.2

getRequiredFlashAttribute

protected java.lang.Object getRequiredFlashAttribute(java.lang.String attributeName)
                                              throws java.lang.IllegalStateException
Returns the required attribute in flash scope; asserts the attribute is present. Flash-scoped attributes are local to the active flow session and cleared on the next user event.

Parameters:
attributeName - the name of the attribute
Returns:
the attribute value
Throws:
java.lang.IllegalStateException - if the attribute was not present
Since:
1.0.2

getRequiredFlashAttribute

protected java.lang.Object getRequiredFlashAttribute(java.lang.String attributeName,
                                                     java.lang.Class requiredType)
                                              throws java.lang.IllegalStateException
Returns the required attribute in flash scope; asserts the attribute is present and of the correct type. Flash-scoped attributes are local to the active flow session and cleared on the next user event.

Parameters:
attributeName - the name of the attribute
Returns:
the attribute value
Throws:
java.lang.IllegalStateException - if the attribute was not present or was of the wrong type

assertActiveFlowEquals

protected void assertActiveFlowEquals(java.lang.String expectedActiveFlowId)
Assert that the active flow session is for the flow with the provided id.

Parameters:
expectedActiveFlowId - the flow id that should have a session active in the tested flow execution

assertFlowExecutionActive

protected void assertFlowExecutionActive()
Assert that the entire flow execution is active; that is, it has not ended and has been started.


assertFlowExecutionEnded

protected void assertFlowExecutionEnded()
Assert that the entire flow execution has ended; that is, it is no longer active.


assertCurrentStateEquals

protected void assertCurrentStateEquals(java.lang.String expectedCurrentStateId)
Assert that the current state of the flow execution equals the provided state id.

Parameters:
expectedCurrentStateId - the expected current state

assertViewNameEquals

protected void assertViewNameEquals(java.lang.String expectedViewName,
                                    ApplicationView viewSelection)
Assert that the view name equals the provided value.

Parameters:
expectedViewName - the expected name
viewSelection - the selected view

assertModelAttributeEquals

protected void assertModelAttributeEquals(java.lang.Object expectedValue,
                                          java.lang.String attributeName,
                                          ApplicationView viewSelection)
Assert that the selected view contains the specified model attribute with the provided expected value.

Parameters:
expectedValue - the expected value
attributeName - the attribute name (can be an expression)
viewSelection - the selected view with a model attribute map to assert against

assertModelAttributeCollectionSize

protected void assertModelAttributeCollectionSize(int expectedSize,
                                                  java.lang.String attributeName,
                                                  ApplicationView viewSelection)
Assert that the selected view contains the specified collection model attribute with the provided expected size.

Parameters:
expectedSize - the expected size
attributeName - the collection attribute name (can be an expression
viewSelection - the selected view with a model attribute map to assert against

assertModelAttributeNotNull

protected void assertModelAttributeNotNull(java.lang.String attributeName,
                                           ApplicationView viewSelection)
Assert that the selected view contains the specified model attribute.

Parameters:
attributeName - the attribute name (can be an expression)
viewSelection - the selected view with a model attribute map to assert against

assertModelAttributeNull

protected void assertModelAttributeNull(java.lang.String attributeName,
                                        ApplicationView viewSelection)
Assert that the selected view does not contain the specified model attribute.

Parameters:
attributeName - the attribute name (can be an expression)
viewSelection - the selected view with a model attribute map to assert against

applicationView

protected ApplicationView applicationView(ViewSelection viewSelection)
Assert that the returned view selection is an instance of ApplicationView.

Parameters:
viewSelection - the view selection

flowExecutionRedirect

protected FlowExecutionRedirect flowExecutionRedirect(ViewSelection viewSelection)
Assert that the returned view selection is an instance of FlowExecutionRedirect.

Parameters:
viewSelection - the view selection

flowDefinitionRedirect

protected FlowDefinitionRedirect flowDefinitionRedirect(ViewSelection viewSelection)
Assert that the returned view selection is an instance of FlowDefinitionRedirect.

Parameters:
viewSelection - the view selection

externalRedirect

protected ExternalRedirect externalRedirect(ViewSelection viewSelection)
Assert that the returned view selection is an instance of ExternalRedirect.

Parameters:
viewSelection - the view selection

nullView

protected void nullView(ViewSelection viewSelection)
Assert that the returned view selection is the ViewSelection.NULL_VIEW.

Parameters:
viewSelection - the view selection

evaluateModelAttributeExpression

protected java.lang.Object evaluateModelAttributeExpression(java.lang.String attributeName,
                                                            java.util.Map model)
Evaluates a model attribute expression.

Parameters:
attributeName - the attribute expression
model - the model map
Returns:
the attribute expression value

createFlowExecutionFactory

protected FlowExecutionFactory createFlowExecutionFactory()
Factory method to create the flow execution factory. Subclasses could override this if they want to use a custom flow execution factory or custom configuration of the flow execution factory, registering flow execution listeners for instance. The default implementation just returns a FlowExecutionImplFactory instance.

Returns:
the flow execution factory

updateFlowExecution

protected void updateFlowExecution(FlowExecution flowExecution)
Directly update the flow execution used by the test by setting it to given flow execution. Use this if you have somehow manipulated the flow execution being tested and want to continue the test with another flow execution.

Parameters:
flowExecution - the flow execution to use

getFlowDefinition

protected abstract FlowDefinition getFlowDefinition()
Returns the flow definition to be tested. Subclasses must implement.

Returns:
the flow definition


Copyright © 2004-2007. All Rights Reserved.