Struts 2 JUnit Plugin Tutorial

Struts 2 的单员测试这么了我很久了,一直没空搞。这次找到这个应该OK。大致梳理下流程:先加依赖,然后创建一个测试用例,继承 StrutsSpringTestCase,因为我们的 SpringStruts配置文件的位置都过,所以要自己设置一下。

Struts 2 JUnit 测试插件教程【Struts 2 JUnit Plugin Tutorial】

When creating unit tests for your Struts 2 application you’ll want to be able to test certain aspects of the action class that normally require the action to be running within a Servlet container and the Struts 2 interceptors to have executed. For example if your Struts 2 action class includes a validate method that checks the values of the instance fields populated by the user’s input on a Struts 2 form, you need the interceptors to have run that get the user’s form field input out of request scope and assign the form field values to the appropriate instance fields.
Struts 2 provides a JUnit plugin library that makes it easier to develop unit tests for testing your Struts 2 action classes. This tutorial will provide an example of how to use the Struts 2 JUnit plugin.
This tutorial assumes the reader knows how to create a Struts 2 application and how to write unit tests using JUnit.
To use the Struts 2 JUnit plugin, you’ll need to have the plugin’s Jar file on your application’s class path. If you’re using Maven you can add this dependency to your pom.xml.

依赖【Struts 2 JUnit Plugin Dependency】

<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-junit-plugin</artifactId>
    <version>STRUTS_VERSION</version>
</dependency>

Of course replace STRUTS_VERSION with the current Struts 2 version number.
For this tutorial we’ll use the following Struts 2 ActionSupport class.

AccountAction.java

public class AccountAction extends ActionSupport {

	private static final long serialVersionUID = 1L;
	private static final Logger logger = Logger.getLogger( AccountAction.class.getName() );
	private Account accountBean;

	public String execute(){
		return SUCCESS;
	}

	public void validate(){

		logger.debug("In method validate. accountBean's state is " + accountBean );

		if ( accountBean.getUserName().length() == 0 ){
			addFieldError( "accountBean.userName", "User name is required." );
		}

		if ( accountBean.getUserName().length() < 5 ) {
			addFieldError( "accountBean.userName", "User name must be at least 5 characters long." );
		}

		if ( accountBean.getUserName().length() > 10 ) {
			addFieldError( "accountBean.userName", "User name cannot be at more than 10 characters long." );
		}
	}

	public Account getAccountBean() {
		return accountBean;
	}

	public void setAccountBean(Account accountBean) {
		this.accountBean = accountBean;
	}

}

The above action class is called after a user enters information on a create account form. Struts takes the user’s input on the form fields and uses those values to populate the state of the Account object (accountBean).
Then the validate method is executed to check the values of the accountBean’s instance fields against certain business rules (for example the length of the username cannot be more than 10).
To test the validate method we can use the Struts 2 JUnit plugin to simulate the Servlet container and Struts 2 framework. Our Junit test class just needs to extend the StrutsTestCase. The StrutsTestCase class is part of the Strut 2 JUnit Plugin library.

测试用例写法【JUnit Test Case For Struts Action Class】

public class TestAccountActionUsingStrutsTestCase extends StrutsTestCase {

    public void testUserNameErrorMessage() throws Exception {

    	request.setParameter("accountBean.userName", "Bruc");
    	request.setParameter("accountBean.password", "test");

    	ActionProxy proxy = getActionProxy("/createaccount");
    	AccountAction accountAction = (AccountAction) proxy.getAction();

        proxy.execute();

        assertTrue("Problem There were no errors present in fieldErrors but there should have been one error present", accountAction.getFieldErrors().size() == 1);
		assertTrue("Problem field account.userName not present in fieldErrors but it should have been", accountAction.getFieldErrors().containsKey("accountBean.userName") );
    }

    public void testUserNameCorrect() throws Exception {

    	request.setParameter("accountBean.userName", "Bruce");
    	request.setParameter("accountBean.password", "test");

    	ActionProxy proxy = getActionProxy("/createaccount");
    	AccountAction accountAction = (AccountAction) proxy.getAction();

        String result = proxy.execute();

        assertTrue("Problem There were errors present in fieldErrors but there should not have been any errors present", accountAction.getFieldErrors().size() == 0);
        assertEquals("Result returned form executing the action was not success but it should have been.", "success", result);
    }
}

The request object above is a MockHttpServletRequest provided by the StrutsTestCase class. We can use this mock Servlet Request object to set values on the request scope as if the user had typed those values into a Struts 2 form input fields. Those values will then be available to the Struts 2 action class.
We then create a proxy of the createaccount action. This action is defined in struts.xml as follows.

struts.xml

<action name="createaccount" class="edu.ku.it.si.struts2_junit_example.action.AccountAction">
	<result>/thankyou.jsp</result>
	<result name="input">/createaccount.jsp</result>
</action>

When we run this test, the proxy of the createaccount action will be executed which will cause the Struts 2 interceptors to fire (so the request scope values will be assigned to the correct Action class instance fields) and then the validate method will be executed.
The two test methods above are used to test the action’s validate method when the username doesn’t meet the business requirements (too few characters) and when the username does meet the business requirements.
Note in the second test method where we have the statement:
String result = proxy.execute();
This statement stores the result returned by the Action class (e.g. “success”) which we can then use in an assert statement to test if the result is what it should be.
assertEquals(“Result returned form executing the action was not success but it should have been.”, “success”, result);
Testing a Struts action against a custom Struts configuration file
Override getConfigPath method to return a comma separated list of paths to a configuration file.

手动指定 struts 配置文件的位置【Specify Struts Configuration File Location Example】

    @Override
    protected String getConfigPath() {
        return "struts-test.xml";
    }

如果用了 Spring 框架,可以手动指定 Spring 配置文件的位置【Testing A Struts Action When Using Spring】

If your Struts application is using Spring to manage class relationships and you want test your Struts action class with the Spring container, then have your test class extend StrutsSpringTestCase instead of StrutsTestCase.
The StrutsSpringTestCase class expects your Spring configuration file to be loaded from classpath:applicationContext.xml (configuration file named applicationContext.xml and in the root of the class path). If your Spring configuration file has a different name or location, in your test class override method:
protected java.lang.String getContextLocations()
For example:
Specify Spring Configuration File Location Example

@Override
public String getContextLocations() {
  return "edu/ku/it/si/tutorial/action/TestAccountAction-context.xml";
}

你以为这样就OK了?然而我却各种 404 ,500, request 为 null。请看:
Struts2 单元测试 —— Struts2-JUnit-Plugin 踩坑记

猜你喜欢

转载自blog.csdn.net/jx520/article/details/89642541