복붙노트

[SPRING] 독립 실행 형 컨텍스트 및 SpringBoot 1.2.5가 포함 된 MockMvcBuilders를 사용한 파일 업로드의 단위 테스트

SPRING

독립 실행 형 컨텍스트 및 SpringBoot 1.2.5가 포함 된 MockMvcBuilders를 사용한 파일 업로드의 단위 테스트

스프링 부트 1.2.5-RELEASE를 사용하고 있습니다. MultipartFile과 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?

이제, Spring Boot의 MultipartAutoConfiguration 클래스에서 MultipartResolver가 자동으로 구성되어있는 것을 볼 수 있습니다. 하지만 MockMvcBuilders의 standaloneSetup을 사용하면이 항목에 액세스 할 수 없습니다.

단위 테스트의 구성을 여러 번 시도해 보았습니다. 특히 여기에 표시된 것처럼 안심할 수도 있지만 솔직히 AService 인스턴스를 조롱 할 수 없기 때문에 이것이 작동하지 않습니다.

어떤 해결책?

해결법

  1. ==============================

    1.단위 테스트 (standaloneSetup (controller) .build ();)와 Spring 통합 테스트 (@RunWith (SpringJUnit4ClassRunner.class))를 결합하려고합니다.

    단위 테스트 (standaloneSetup (controller) .build ();)와 Spring 통합 테스트 (@RunWith (SpringJUnit4ClassRunner.class))를 결합하려고합니다.

    하나 또는 다른 것을하십시오.

  2. ==============================

    2.나는 lkrnak이 제안한 것과 Mockito @Spy 기능을 혼합했다. 나는 전화를하기 위해 REST-Assured를 사용한다. 그래서 나는 다음과 같이했다.

    나는 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
    }
    
  3. ==============================

    3.오류는 요청이 다중 부분 요청이 아님을 나타냅니다. 즉, 그 시점에서 파싱 된 것으로 예상됩니다. 그러나 MockMvc 테스트에는 실제 요청이 없습니다. 그냥 모의 요청과 응답 일뿐입니다. 따라서 모의 파일 업로드 요청을 설정하려면 perform.fileUpload (...)를 사용해야합니다.

    오류는 요청이 다중 부분 요청이 아님을 나타냅니다. 즉, 그 시점에서 파싱 된 것으로 예상됩니다. 그러나 MockMvc 테스트에는 실제 요청이 없습니다. 그냥 모의 요청과 응답 일뿐입니다. 따라서 모의 파일 업로드 요청을 설정하려면 perform.fileUpload (...)를 사용해야합니다.

  4. from https://stackoverflow.com/questions/32293550/unit-test-of-file-upload-using-mockmvcbuilders-with-standalone-context-and-sprin by cc-by-sa and MIT license