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:st...@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-unsubscr...@struts.apache.org
For additional commands, e-mail: user-h...@struts.apache.org

Reply via email to