Java SpringWebFlow:为JUnit测试设置请求参数 介绍

Java SpringWebFlow:为JUnit测试设置请求参数 介绍,java,spring,mocking,junit4,spring-webflow-2,Java,Spring,Mocking,Junit4,Spring Webflow 2,我有一个Java/Tomcat/Spring2.5/SpringWebFlow2.0.9Web应用程序。为了测试一些页面,我创建了JUnit测试,它为表单对象设置值并模拟来自浏览器的请求。JUnit测试类如下所示: @TestExecutionListeners({ DependencyInjectionTestExecutionListener.class }) @ContextConfiguration(locations = { "classpath:/WebTests-context.x

我有一个Java/Tomcat/Spring2.5/SpringWebFlow2.0.9Web应用程序。为了测试一些页面,我创建了JUnit测试,它为表单对象设置值并模拟来自浏览器的请求。JUnit测试类如下所示:

@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class })
@ContextConfiguration(locations = { "classpath:/WebTests-context.xml", "classpath:/messageSourceConfig.xml" })
@RunWith(SpringJUnit4ClassRunner.class)

public class InitechValidatorTests {

    protected MockHttpSession session;
    protected MockHttpServletRequest request;

    //test methods omitted

    protected void startSession() {
        session = new MockHttpSession();
    }

    protected void endSession() {
        session.clearAttributes();
        session = null;
    }

    protected void startRequest() {
        request = new MockHttpServletRequest();
        request.setSession(session);
        RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));

        MockRequestContext mrc = new MockRequestContext();
        org.springframework.webflow.execution.RequestContextHolder.setRequestContext(mrc);

        MessageContext messageContext = org.springframework.webflow.execution.RequestContextHolder.getRequestContext()
                .getMessageContext();
        this.validationContext.setMessageContext(messageContext);
    }

    protected void endRequest() {
        ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).requestCompleted();
        RequestContextHolder.resetRequestAttributes();
        request = null;

        org.springframework.webflow.execution.RequestContextHolder.setRequestContext(null);
    }
}
RequestContext requestContext = RequestContextHolder.getRequestContext();
ExternalContext externalContext = requestContext.getExternalContext();
String printPressed = externalContext.getRequestParameterMap().get("printPressed");
org.springframework.webflow.execution.RequestContext requestContext = org.springframework.webflow.execution.RequestContextHolder
                    .getRequestContext();
ExternalContext externalContext = requestContext.getExternalContext();
Map requestParamMap = externalContext.getRequestParameterMap().asMap();
requestParamMap.put("printPressed", "true");
对于每个测试方法,我调用startRequest和endRequest方法(在第一个测试方法之前调用startSession,在最后一个测试方法之后调用endSession)。如果没有这个构造,我无法在我正在测试的代码中使用例如RequestContextHolder

问题 在要测试的类中,我从web流中读取请求参数的内容,如下所示:

@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class })
@ContextConfiguration(locations = { "classpath:/WebTests-context.xml", "classpath:/messageSourceConfig.xml" })
@RunWith(SpringJUnit4ClassRunner.class)

public class InitechValidatorTests {

    protected MockHttpSession session;
    protected MockHttpServletRequest request;

    //test methods omitted

    protected void startSession() {
        session = new MockHttpSession();
    }

    protected void endSession() {
        session.clearAttributes();
        session = null;
    }

    protected void startRequest() {
        request = new MockHttpServletRequest();
        request.setSession(session);
        RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));

        MockRequestContext mrc = new MockRequestContext();
        org.springframework.webflow.execution.RequestContextHolder.setRequestContext(mrc);

        MessageContext messageContext = org.springframework.webflow.execution.RequestContextHolder.getRequestContext()
                .getMessageContext();
        this.validationContext.setMessageContext(messageContext);
    }

    protected void endRequest() {
        ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).requestCompleted();
        RequestContextHolder.resetRequestAttributes();
        request = null;

        org.springframework.webflow.execution.RequestContextHolder.setRequestContext(null);
    }
}
RequestContext requestContext = RequestContextHolder.getRequestContext();
ExternalContext externalContext = requestContext.getExternalContext();
String printPressed = externalContext.getRequestParameterMap().get("printPressed");
org.springframework.webflow.execution.RequestContext requestContext = org.springframework.webflow.execution.RequestContextHolder
                    .getRequestContext();
ExternalContext externalContext = requestContext.getExternalContext();
Map requestParamMap = externalContext.getRequestParameterMap().asMap();
requestParamMap.put("printPressed", "true");
我需要在JUnit测试方法中设置“printPressed”请求参数,如下所示:

@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class })
@ContextConfiguration(locations = { "classpath:/WebTests-context.xml", "classpath:/messageSourceConfig.xml" })
@RunWith(SpringJUnit4ClassRunner.class)

public class InitechValidatorTests {

    protected MockHttpSession session;
    protected MockHttpServletRequest request;

    //test methods omitted

    protected void startSession() {
        session = new MockHttpSession();
    }

    protected void endSession() {
        session.clearAttributes();
        session = null;
    }

    protected void startRequest() {
        request = new MockHttpServletRequest();
        request.setSession(session);
        RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));

        MockRequestContext mrc = new MockRequestContext();
        org.springframework.webflow.execution.RequestContextHolder.setRequestContext(mrc);

        MessageContext messageContext = org.springframework.webflow.execution.RequestContextHolder.getRequestContext()
                .getMessageContext();
        this.validationContext.setMessageContext(messageContext);
    }

    protected void endRequest() {
        ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).requestCompleted();
        RequestContextHolder.resetRequestAttributes();
        request = null;

        org.springframework.webflow.execution.RequestContextHolder.setRequestContext(null);
    }
}
RequestContext requestContext = RequestContextHolder.getRequestContext();
ExternalContext externalContext = requestContext.getExternalContext();
String printPressed = externalContext.getRequestParameterMap().get("printPressed");
org.springframework.webflow.execution.RequestContext requestContext = org.springframework.webflow.execution.RequestContextHolder
                    .getRequestContext();
ExternalContext externalContext = requestContext.getExternalContext();
Map requestParamMap = externalContext.getRequestParameterMap().asMap();
requestParamMap.put("printPressed", "true");
然而,这是不可能的,因为映射是不可变的,并且会导致不支持的操作异常

问题是:如何将请求参数设置为类中的requestParameterMap?返回的参数映射是不可变的,因此我无法在其中添加参数。我注意到,例如,有一个对象,听起来很有希望:“一个参数映射的扩展,允许参数的变异。作为测试的存根很有用。”


如何将MockParameterMap注入测试类中的ExternalContext?或者是否有其他方法来设置单元测试的请求参数?

通过修改startRequest方法来解决问题,以便我将设置为一个新对象,该对象设置如下:

MockParameterMap mpp = new MockParameterMap();
MockExternalContext mec = new MockExternalContext(mpp);
mrc.setExternalContext(mec);
org.springframework.webflow.execution.RequestContext requestContext = org.springframework.webflow.execution.RequestContextHolder
                    .getRequestContext();
ExternalContext externalContext = requestContext.getExternalContext();
MockParameterMap requestParameterMap = (MockParameterMap) externalContext.getRequestParameterMap();
requestParameterMap.put("printPressed", "true");
然后在JUnit测试方法中,我可以设置以下参数:

MockParameterMap mpp = new MockParameterMap();
MockExternalContext mec = new MockExternalContext(mpp);
mrc.setExternalContext(mec);
org.springframework.webflow.execution.RequestContext requestContext = org.springframework.webflow.execution.RequestContextHolder
                    .getRequestContext();
ExternalContext externalContext = requestContext.getExternalContext();
MockParameterMap requestParameterMap = (MockParameterMap) externalContext.getRequestParameterMap();
requestParameterMap.put("printPressed", "true");