1
votes

I have a service method which accepts CommonsMultipartFile and uploads it to server

class ExampleService() {
    def saveFile(CommonsMultipartFile file) {
        // some validation code for file
    }
}

tried using both MockMultipartHttpServletRequest and GrailsMockMultipartFile.

In case of MockMultipartHttpServletRequest getting error as:

|  org.codehaus.groovy.runtime.typehandling.GroovyCastException: 
Cannot cast object 'org.springframework.mock.web.MockMultipartFile@2f39360' 
with class 'org.springframework.mock.web.MockMultipartFile' to 
class 'org.springframework.web.multipart.commons.CommonsMultipartFile'

Same goes with GrailsMockMultipartFile getting error as:

|  org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot 
cast object 'org.codehaus.groovy.grails.plugins.testing.GrailsMockMultipartFile@1022f0bd' 
with class 'org.codehaus.groovy.grails.plugins.testing.GrailsMockMultipartFile' to 
class 'org.springframework.web.multipart.commons.CommonsMultipartFile'

referred this stack overflow question.

How should I mock CommonsMultipartFile and pass it as argument inside my test case ?


Solution

I found solution please check my answer

2
Can you change the saveFile() method to use the interface MultipartFile rather than the specific implementation? If so, it should be easier to mock. - cjstehno
As @cjstehno says, always use interfaces where possible, e.g. List and Map instead of ArrayList and HashMap, and MultipartFile in this case. Only use implemtation class names when instantiating and when accessing methods that aren't in an interface - Burt Beckwith
@cjstehno convert your comment to an answer so we can upvote it - Burt Beckwith
Thanks for such a quick response guys. saveFile() method do some additional code other than saving a file. I don't want to change my existing method implementation. - Laxmi Salunkhe
@LaxmiSalunkhe - you would not be changing your implementation by using the interface. It would still be the same implementation passed in. If you code requires a specific implementation you might want to investigate refactoring to remove the specific dependency. That API is pretty robust without ever needing to use a specific implementation class. - cjstehno

2 Answers

1
votes

After going through different stack overflow links and CommonsMultipartFile JDK I come up with this solution

Please let me know if I am using wrong approach @burtbeckwith

File getTestFile(String fileName = "") {
    //Code which create file instance 
}

// Inside my test case I have created CommonsMultipartFile test file and used it.
DiskFileItemFactory factory = new DiskFileItemFactory()
FileItem fileItem = factory.createItem( "file", "multipart/form-data", false, "logo.png" )
IOUtils.copy(new FileInputStream(getTestFile()), fileItem.getOutputStream())
CommonsMultipartFile testFile = new CommonsMultipartFile(fileItem)
1
votes

If you change the saveFile(CommonsMultipartFile) method to accept an instance of the interface MultipartFile rather than the specific implementation it will be easier to mock and you should lose no functionality.

saveFile(MultipartFile)