使用具有独立上下文和SpringBoot 1.2.5的MockMvcBuilders进行文件上传的单元测试

问题描述

我混合了lkrnak的建议和Mockito的@Spy功能。我使用REST-Assured进行通话。所以,我做了如下:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
@WebAppConfiguration
@IntegrationTest({"server.port:0"})
public class ControllerTest{

    {
      System.setProperty("spring.profiles.active", "unit-test");
    }


    @Autowired
    @Spy
    AService aService;

    @Autowired
    @InjectMocks
    MyRESTController controller;

    @Value("${local.server.port}")
    int port;


  @Before public void setUp(){
    RestAssured.port = port;

    MockitoAnnotations.initMocks(this);
  }

  @Test
  public void testFileUpload() throws Exception{
        final File file = getFileFromresource(fileName);

        donothing().when(aService)  
             .doSomethingOnDBWith(any(multipartfile.class), any(String.class));

        given()
          .multiPart("file", file)
          .multiPart("something", ":(")
          .when().post("/file-upload")
          .then().(HttpStatus.CREATED.value());
    }
}

服务定义为

@Profile("unit-test")
@Primary
@Service
public class MockAService implements AService {
  //empty methods implementation
}

解决方法

我正在使用Spring Boot 1.2.5-RELEASE。我有一个接收a MultipartFile和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);
  }
}

现在,该服务运行良好。我用PostMan对其进行了测试,并且一切都按预期进行。不幸的是,我无法为该代码编写独立的单元测试。当前的单元测试是:

@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());
    }
}

测试失败

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

现在,在MultipartAutoConfigurationSpring Boot 的类中,我看到a
MultipartResolver是自动配置的。但是,我想这与standaloneSetupMockMvcBuilders我无法访问此。

我尝试了多种配置的单元测试,为简洁起见,我没有报告。特别是,我也试过休息,保证如图所示这里,但说实话,这并不工作,因为它似乎我不能嘲笑的AService实例。

有什么办法吗?