test support refinements

This commit is contained in:
Keith Donald
2007-11-07 23:16:00 +00:00
parent 2a1b6f1621
commit d51ad6f388
6 changed files with 79 additions and 31 deletions

View File

@@ -18,6 +18,7 @@ import org.springframework.util.ClassUtils;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.InternalResourceView;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.webflow.action.ViewFactoryActionAdapter;
import org.springframework.webflow.core.collection.ParameterMap;
import org.springframework.webflow.engine.builder.ViewFactoryCreator;
import org.springframework.webflow.execution.Action;
@@ -239,21 +240,4 @@ public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationCon
}
/**
* Simple adapter that adapts a view factory render cycle to the action interface.
* @author Keith Donald
*/
private static class ViewFactoryActionAdapter implements Action {
private ViewFactory viewFactory;
public ViewFactoryActionAdapter(ViewFactory viewFactory) {
this.viewFactory = viewFactory;
}
public Event execute(RequestContext context) throws Exception {
viewFactory.getView(context).render();
return new Event(this, "success");
}
}
}

View File

@@ -15,28 +15,30 @@ class FlowBuilderSystemDefaults {
defaultServices = new FlowBuilderServices();
defaultServices.setFlowArtifactFactory(new FlowArtifactFactory());
defaultServices.setBeanInvokingActionFactory(new BeanInvokingActionFactory());
defaultServices.setViewFactoryCreator(new MockViewFactoryCreator());
defaultServices.setConversionService(new DefaultConversionService());
defaultServices.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
defaultServices.setResourceLoader(new DefaultResourceLoader());
defaultServices.setBeanFactory(new StaticListableBeanFactory());
}
public static FlowBuilderServices get() {
return new FlowBuilderSystemDefaults().createBuilderServices();
}
public FlowBuilderServices createBuilderServices() {
FlowBuilderServices builderServices = new FlowBuilderServices();
applyDefaults(builderServices);
return builderServices;
}
public void applyDefaults(FlowBuilderServices services) {
private void applyDefaults(FlowBuilderServices services) {
services.setFlowArtifactFactory(defaultServices.getFlowArtifactFactory());
services.setBeanInvokingActionFactory(defaultServices.getBeanInvokingActionFactory());
services.setViewFactoryCreator(defaultServices.getViewFactoryCreator());
services.setConversionService(defaultServices.getConversionService());
services.setExpressionParser(defaultServices.getExpressionParser());
services.setResourceLoader(defaultServices.getResourceLoader());
services.setBeanFactory(defaultServices.getBeanFactory());
}
public static FlowBuilderServices get() {
return new FlowBuilderSystemDefaults().createBuilderServices();
}
}

View File

@@ -17,6 +17,7 @@ package org.springframework.webflow.test.execution;
import org.springframework.core.io.Resource;
import org.springframework.webflow.config.FlowDefinitionResource;
import org.springframework.webflow.config.FlowDefinitionResourceFactory;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.definition.FlowDefinition;
import org.springframework.webflow.engine.Flow;
@@ -47,6 +48,11 @@ public abstract class AbstractExternalizedFlowExecutionTests extends AbstractFlo
*/
private boolean cacheFlowDefinition = false;
/**
* A helper for constructing paths to flow definition resources in the filesystem, classpath, or other location.
*/
private FlowDefinitionResourceFactory resourceFactory = new FlowDefinitionResourceFactory();
/**
* Constructs a default externalized flow execution test.
* @see #setName(String)
@@ -137,7 +143,7 @@ public abstract class AbstractExternalizedFlowExecutionTests extends AbstractFlo
* @return the built flow definition, ready for execution
*/
protected final Flow buildFlow() {
FlowDefinitionResource resource = getFlowDefinitionResource();
FlowDefinitionResource resource = getResource(resourceFactory);
FlowBuilderContext builderContext = createFlowBuilderContext(resource);
FlowBuilder builder = createFlowBuilder(resource.getPath());
FlowAssembler assembler = new FlowAssembler(builder, builderContext);
@@ -166,9 +172,10 @@ public abstract class AbstractExternalizedFlowExecutionTests extends AbstractFlo
/**
* Get the flow definition to be tested.
* @param a helper for constructing the resource to be tested
* @return the flow definition resource
*/
protected abstract FlowDefinitionResource getFlowDefinitionResource();
protected abstract FlowDefinitionResource getResource(FlowDefinitionResourceFactory resourceFactory);
/**
* Create the flow builder to build the flow at the specified resource location.

View File

@@ -24,6 +24,8 @@ import org.springframework.webflow.engine.impl.FlowExecutionImplFactory;
import org.springframework.webflow.execution.FlowExecution;
import org.springframework.webflow.execution.FlowExecutionException;
import org.springframework.webflow.execution.FlowExecutionFactory;
import org.springframework.webflow.test.MockExternalContext;
import org.springframework.webflow.test.MockParameterMap;
/**
* Base class for integration tests that verify a flow executes as expected. Flow execution tests captured by subclasses
@@ -117,6 +119,45 @@ public abstract class AbstractFlowExecutionTests extends TestCase {
flowExecution.resume(context);
}
/**
* Signal the event against the paused flow execution. The event id will be translated into a Event object by the
* configured view factory and raised as an Event against the current view state. The event will cause the flow to
* change states if it matches a transition.
* @param eventId the event identifier
*/
protected void signalEvent(String eventId) {
MockExternalContext context = new MockExternalContext();
context.putRequestParameter("_eventId", eventId);
resumeFlow(context);
}
/**
* Signal the event against the paused flow execution. The event id will be translated into a Event object by the
* configured view factory and raised as an Event against the current view state. The event will cause the flow to
* change states if it matches a transition.
* @param eventId the event identifier
* @param input event input parameters
*/
protected void signalEvent(String eventId, MockParameterMap input) {
MockExternalContext context = new MockExternalContext(input);
context.putRequestParameter("_eventId", eventId);
resumeFlow(context);
}
/**
* Signal the event against the paused flow execution. The event id will be translated into a Event object by the
* configured view factory and raised as an Event against the current view state. The event will cause the flow to
* change states if it matches a transition.
* @param eventId the event identifier
* @param parameterName the name of the parameter
* @param parameterValue the value of the parameter
*/
protected void signalEvent(String eventId, String parameterName, String parameterValue) {
MockParameterMap input = new MockParameterMap();
input.put(parameterName, parameterValue);
signalEvent(eventId, input);
}
// convenience accessors
/**

View File

@@ -22,6 +22,7 @@ import org.springframework.binding.mapping.AttributeMapper;
import org.springframework.binding.mapping.MappingContext;
import org.springframework.webflow.config.FlowDefinitionResource;
import org.springframework.webflow.config.FlowDefinitionResourceFactory;
import org.springframework.webflow.context.ExternalContext;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.engine.EndState;
import org.springframework.webflow.engine.Flow;
@@ -32,21 +33,34 @@ import org.springframework.webflow.test.execution.AbstractXmlFlowExecutionTests;
*/
public class SearchFlowExecutionTests extends AbstractXmlFlowExecutionTests {
protected FlowDefinitionResource getFlowDefinitionResource() {
return new FlowDefinitionResourceFactory().createClassPathResource("search-flow.xml", getClass());
protected FlowDefinitionResource getResource(FlowDefinitionResourceFactory resourceFactory) {
return resourceFactory.createClassPathResource("search-flow.xml", getClass());
}
public void testStartFlow() {
// startFlow(new MockExternalContext());
ExternalContext context = new MockExternalContext();
startFlow(context);
assertCurrentStateEquals("enterCriteria");
}
public void testCriteriaSubmitSuccess() {
startFlow(new MockExternalContext());
signalEvent("search");
assertCurrentStateEquals("displayResults");
}
public void testNewSearch() {
startFlow(new MockExternalContext());
signalEvent("search");
signalEvent("newSearch");
assertCurrentStateEquals("enterCriteria");
}
public void testSelectValidResult() {
startFlow(new MockExternalContext());
signalEvent("search");
signalEvent("select", "id", "1");
assertCurrentStateEquals("displayResults");
}
protected void configure(MockFlowBuilderContext builderContext) {
@@ -63,7 +77,7 @@ public class SearchFlowExecutionTests extends AbstractXmlFlowExecutionTests {
builderContext.registerBean("phonebook", new TestPhoneBook());
}
static class TestPhoneBook {
public static class TestPhoneBook {
public List search(Object criteria) {
ArrayList res = new ArrayList();
res.add(new Object());

View File

@@ -2,7 +2,7 @@
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<start-state idref="enterCriteria"/>
@@ -19,7 +19,7 @@
<render-actions>
<bean-action bean="phonebook" method="search">
<method-arguments>
<argument expression="flowScope.searchCriteria"/>
<argument expression="${flowScope.searchCriteria}"/>
</method-arguments>
<method-result name="results"/>
</bean-action>
@@ -31,7 +31,7 @@
<subflow-state id="browseDetails" flow="detail-flow">
<attribute-mapper>
<input-mapper>
<mapping source="requestParameters.id" target="id" from="string" to="long"/>
<mapping source="${requestParameters.id}" target="${id}" from="string" to="long"/>
</input-mapper>
</attribute-mapper>
<transition on="finish" to="displayResults"/>