0

I am unable to write a test that uploads a file to my controller.

Of all the occurrences of this problem I have seen nothing has worked out for me.

I am able to upload and store a file from my webapp, but when I run my test, the file in the controller is always null

Application

import com.mangofactory.swagger.configuration.SpringSwaggerConfig;
import com.mangofactory.swagger.plugin.EnableSwagger;
import com.mangofactory.swagger.plugin.SwaggerSpringMvcPlugin;
import com.wordnik.swagger.model.ApiInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableSwagger
public class Application {

private SpringSwaggerConfig springSwaggerConfig;

@Autowired
public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig) {
    this.springSwaggerConfig = springSwaggerConfig;
}

@Bean
        // Don't forget the @Bean annotation
public SwaggerSpringMvcPlugin customImplementation() {
    return new SwaggerSpringMvcPlugin(this.springSwaggerConfig).apiInfo(
            apiInfo()).includePatterns("/api/.*");
}

private ApiInfo apiInfo() {
    return new ApiInfo("Application", "Upload files", "Play nice", "reece@reececo.com", "Go for your life", "DoesNotExist");
}

public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Controller

@RequestMapping(method = POST)
@ApiOperation(value = "Multipart file upload", notes = "Upload a file to an ID")
@ApiResponses(value = { @ApiResponse(code = 200, message = "") })
public @ResponseBody String uploadFile(MultipartFile file, @PathVariable String key) {

// Store File

}

Test

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = EasyshareApplication.class)
@WebAppConfiguration
@IntegrationTest
public class FileUploadControllerTest {

@Autowired
private UploadRepository uploadRepository;

private MockMvc restFileMockMvc;

@Before
public void setup() throws Exception {
    FileController fileController= new FileController();
    ReflectionTestUtils.setField(fileController, "uploadRepository", uploadRepository);
    this.restFileMockMvc = MockMvcBuilders.standaloneSetup(fileController).build();
}

@Test
public void testFileUpload() throws Exception{
    MockMultipartFile mockFile = new MockMultipartFile("data", "DATADATADATDATADATA".getBytes());

    Upload upload = uploadRepository.save(new Upload("Description"));
    String key = upload.getKey();

    restFileMockMvc
            .perform(fileUpload("/api/uploads/" + key + "/file")
                .file(mockFile)
                    .param("name", "xyz")
                    .contentType(MediaType.MULTIPART_FORM_DATA))
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.upload").exists())
            .andExpect(jsonPath("$.ID").exists())
            .andExpect(jsonPath("$.filename").exists())
            .andExpect(jsonPath("$.contentType").exists())
            .andExpect(jsonPath("$.length").exists());
}

@Test
public void testMissingFileUpload() throws Exception{
    String key = "shouldntNeedAKey";

    restFileMockMvc
            .perform(fileUpload("/api/uploads/" + key + "/file"))
            .andExpect(status().isBadRequest());
}
}
Reece
  • 714
  • 2
  • 9
  • 24
  • Do you have a `CommonsMultipartResolver` configured in your mvc config? – s.ijpma Sep 10 '15 at 10:29
  • I did try that as suggested in http://stackoverflow.com/questions/21800726/using-spring-mvc-test-to-unit-test-multipart-post-request - and have commons-fileupload version 1.3.1 in my pom – Reece Sep 10 '15 at 11:18
  • For those who are wondering where is fileUpload, do this import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; – raksja May 27 '16 at 20:31

1 Answers1

3

In case someone stumbles upon this, I did resolve this issue.

I simply had to annotate the MulipartFile in my REST controller with:

@RequestParam(name = "file"), @RequestPart also works.

Controller now looks like this:

@RequestMapping(method = POST)
@ApiOperation(value = "Multipart file upload", notes = "Upload a file to an ID")
@ApiResponses(value = { @ApiResponse(code = 200, message = "") })
public @ResponseBody String uploadFile(@RequestParam(name = "file") MultipartFile file, @PathVariable String key) {

// Store File

}
Reece
  • 714
  • 2
  • 9
  • 24