|
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 |
|
Coincidentally, yesterday I was struggling with testing a file upload.
I was not using S2 as web framework but I was using Commons Fileupload, which IIRC is the default S2 upload component. I must say that my first strategy was trying to use Spring's MockMultipartHttpServletRequest and MockMultipartFile to simulate the request, without any luck, so I ended up just writing the plain request by hand: request = new MockHttpServletRequest(); request.setMethod("POST"); request.setContentType("multipart/form-data; boundary=AaB03x"); request.setContent(("--AaB03x\r\n" + "Content-Disposition: form-data; name=\"archivo\"; filename=\"texto.txt\"\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "This is the content of the file\n" + "\r\n" + "--AaB03x\r\n" + "Content-Disposition: form-data; name=\"id\"\r\n" + "\r\n" + "1\r\n" + "--AaB03x--\r\n").getBytes("US-ASCII")); simulating the following form: <form method="post" action="controller?event=cargarMaterial" enctype="multipart/form-data"> <input type="hidden" name="id" value="${reunion.idreunion}"/> <input type="file" name="archivo" size="50" /> <input type="submit" name="btnSubmit" value="Guardar" /> </form> Important: respect the \r\n's and the final boundary with the extra "--" at the end of the form. commons upload version: 1.2.2. HTH, Gabriel 2012/4/25 Steve Higham <[hidden email]>: > 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: [hidden email] For additional commands, e-mail: [hidden email] |
|
First of all, I assume you're trying to test your own code, not the
framework. With that in mind, by the time the file gets to your action, it's just a series of parameters (which could be slightly different depending on which underlying Multipart support you are using). So, my suggestion would be to just mock in values for the parameters your action is expecting. (*Chris*) On Wed, Apr 25, 2012 at 6:36 AM, Gabriel Belingueres <[hidden email]>wrote: > Coincidentally, yesterday I was struggling with testing a file upload. > I was not using S2 as web framework but I was using Commons > Fileupload, which IIRC is the default S2 upload component. > > I must say that my first strategy was trying to use Spring's > MockMultipartHttpServletRequest and MockMultipartFile to simulate the > request, without any luck, so I ended up just writing the plain > request by hand: > > request = new MockHttpServletRequest(); > request.setMethod("POST"); > request.setContentType("multipart/form-data; boundary=AaB03x"); > > request.setContent(("--AaB03x\r\n" + > "Content-Disposition: form-data; name=\"archivo\"; > filename=\"texto.txt\"\r\n" + > "Content-Type: text/plain\r\n" + > "\r\n" + > "This is the content of the file\n" + > "\r\n" + > "--AaB03x\r\n" + > "Content-Disposition: form-data; name=\"id\"\r\n" + > "\r\n" + > "1\r\n" + > "--AaB03x--\r\n").getBytes("US-ASCII")); > > simulating the following form: > > <form method="post" action="controller?event=cargarMaterial" > enctype="multipart/form-data"> > <input type="hidden" name="id" value="${reunion.idreunion}"/> > <input type="file" name="archivo" size="50" /> > <input type="submit" name="btnSubmit" value="Guardar" /> > </form> > > Important: respect the \r\n's and the final boundary with the extra > "--" at the end of the form. > > commons upload version: 1.2.2. > > HTH, > Gabriel > > 2012/4/25 Steve Higham <[hidden email]>: > > 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: [hidden email] > For additional commands, e-mail: [hidden email] > > |
|
In reply to this post by Steve Higham
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:[hidden email]] 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: [hidden email] For additional commands, e-mail: [hidden email] |
| Powered by Nabble | Edit this page |
