struts-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Steve Higham" <st...@sjlt.co.uk>
Subject RE: StrutsTestCase, jUnit and file upload
Date Thu, 26 Apr 2012 11:39:39 GMT
Thanks to Chris, Gabriel for your comments.

I finally got this to work yesterday. A neat solution probably requires
refactoring StrutsTestCase and deriving a new class
(StrutsMultipartTestCase) from it. In the meantime the following changes
will work subject to a couple of limitations: -

This only supports upload of a single file - although fairly simple to
extend for multiple files.
I've use Mockito for a couple of mocks
It's not very clean :-(

First you need spring-web-x.y.z.jar on your classpath. This comes with the
junit plugin.

Your test class needs the following override. This is a cut & paste job from
StrutsTestCase except for the request creation line.

/**
 * We need to override this method so we can use class 
 * MockMultipartHttpServletRequest for the request.
 */
@Override
protected void initServletMockObjects() 
{
  servletContext = new MockServletContext(resourceLoader);
  response = new MockHttpServletResponse();
  request = new MockMultipartHttpServletRequest();
  pageContext = new MockPageContext(servletContext, request, response);
}

We now need a new version of getActionProxy with additional parameters as
follows: -

/**
 * We need our own version to handle the file uploading
 * @param uri  struts action uri
 * @param contentType  mime content type
 * @param filename  name reported to action
 * @param file  uploaded file
 * @return  ActionProxy
 */
protected ActionProxy 
getActionProxy (String uri, String contentType, String filename, File file)
{
	// Create the proxy
	ActionProxy result = super.getActionProxy (uri);

	// Not part of upload but I think required for SessionAware
	ActionContext context = result.getInvocation ().getInvocationContext
();
	if (context.getSession () == null)
	{
		context.setSession (new HashMap<String, Object> ());
	}
	
	// Wrap the request in a MultiPartRequestWrapper
	MultiPartRequest mpr = 
			createMultiPartRequest (contentType, filename,
file);
	MultiPartRequestWrapper wrapper = 
			new MultiPartRequestWrapper (mpr, request, null);
	ServletActionContext.setRequest (wrapper);
	
	return result;
}

protected MultiPartRequest 
createMultiPartRequest (String contentType, String fileName, File file)
{
	MultiPartRequest result = Mockito.mock (MultiPartRequest.class);
	Vector<String> fileParameterNames = new Vector<String> ();
	fileParameterNames.add (PROP_NAME);
	Enumeration<String> enumFpn = fileParameterNames.elements ();
	Mockito.when (result.getFileParameterNames ()).thenReturn (enumFpn);
	String [] contentTypes = new String [1];
	contentTypes [0] = contentType;
	Mockito.when (result.getContentType (PROP_NAME)).thenReturn
(contentTypes);
	String [] fileNames = new String [1];
	fileNames [0] = fileName;
	Mockito.when (result.getFileNames (PROP_NAME)).thenReturn
(fileNames);
	File [] files = new File [1];
	files [0] = file;
	Mockito.when (result.getFile (PROP_NAME)).thenReturn (files);
	
	return result;
}

private static final String PROP_NAME = "propertyName";

This assumes that your upload action has methods setPropertyName (File),
setPropertyNameContentType (String), setPropertyNameFileName (String).

The @Test methods now include the following: -

File uploadedFile = new File ("path to test file");
ActionProxy proxy = getActionProxy ("uri", "content type e.g. text/csv",
file.getName (), file);
assertTrue (proxy.execute ().equals ("expected action result");

Note that the calls to the action are generated internally. You don't need
any request.setParameter (...) calls.

Cheers,

Steve

-----Original Message-----
From: Steve Higham [mailto:steve@sjlt.co.uk] 
Sent: 25 April 2012 11:08
To: 'Struts Users Mailing List'
Subject: StrutsTestCase, jUnit and file upload

I'm currently using StrutsTestCase and jUnit to component test my Actions
within the Struts context using a Mockito mock as my Model.

 

This is working fine. I can call request.setParamater ("paramName",
"paramValue") from the test class and, when executed, Struts will call the
corresponding setParamName ("paramValue") on my Action.

 

However I now wish to test "file upload" Actions. In normal use the
FileUploadInterceptor will call setUploadedFile (java.io.File file) on the
action. However I can't see any methods on the StrutsTestCase request object
which will prepare the request with an uploaded file. Has anyone got this to
work?

 

Steve Higham

 



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Mime
View raw message