Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
178 views
in Technique[技术] by (71.8m points)

java - Unit Test of file upload using MockMvcBuilders with standalone context and SpringBoot 1.2.5

I'm using Spring Boot 1.2.5-RELEASE. I have a controller that receive a MultipartFile and a String

@RestController
@RequestMapping("file-upload")
public class MyRESTController {

  @Autowired
  private AService aService;

  @RequestMapping(method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  @ResponseStatus(HttpStatus.CREATED)
  public void fileUpload(
      @RequestParam(value = "file", required = true) final MultipartFile file,
      @RequestParam(value = "something", required = true) final String something) {
   aService.doSomethingOnDBWith(file, value);
  }
}

Now, the service works well. I tested it with PostMan and eveything goes as expected. Unfortunately, I cannot write a standalone unit test for that code. The current unit test is:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
@WebAppConfiguration
public class ControllerTest{

    MockMvc mockMvc;

    @Mock
    AService aService;

    @InjectMocks
    MyRESTController controller;

  @Before public void setUp(){
    MockitoAnnotations.initMocks(this);
    this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
  }

  @Test
  public void testFileUpload() throws Exception{
        final File file = getFileFromResource(fileName);
        //File is correctly loaded
        final MockMultipartFile multipartFile = new MockMultipartFile("aMultiPartFile.txt", new FileInputStream(file));

        doNothing().when(aService).doSomethingOnDBWith(any(MultipartFile.class), any(String.class));

        mockMvc.perform(
                post("/file-upload")
                        .requestAttr("file", multipartFile.getBytes())
                        .requestAttr("something", ":(")
                        .contentType(MediaType.MULTIPART_FORM_DATA_VALUE))
                .andExpect(status().isCreated());
    }
}

Test fails with

java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?

Now, in the MultipartAutoConfiguration class from Spring Boot I see that a MultipartResolver is auto configured. But, I guess that with the standaloneSetup of MockMvcBuilders I cannot access this.

I tried several configurations of the unit test that I don't report for brevity. Especially, I also tried rest-assured as shown here, but honestly this doesn't work because it seems that I cannot mock the AService instance.

Any solution?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You are trying to combine here unit test (standaloneSetup(controller).build();) with Spring integration test (@RunWith(SpringJUnit4ClassRunner.class)).

Do one or the other.

  1. Integration test will need to use something like code below. The problem would be faking of beans. There are ways to fake such bean with @Primary annotation and @Profile annotation (you create testing bean which will override main production bean). I have some examples of such faking of Spring beans (e.g. this bean is replaced by this bean in this test).

    @Autowired
    private WebApplicationContext webApplicationContext;
    
    @BeforeMethod
    public void init() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }
    
  2. Secodn option is to remove @RunWith(SpringJUnit4ClassRunner.class) and other class level configuration on your test and test controller without Spring Context with standalone setup. That way you can't test validation annotations on your controller, but you can use Spring MVC annotations. Advantage is possibility to fake beans via Mockito (e.g. via InjectMocks and Mock annotations)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...