代码之家  ›  专栏  ›  技术社区  ›  Guido Flohr

使用MockMvc测试spring下载链接时“找不到可接受的表示”

  •  0
  • Guido Flohr  · 技术社区  · 7 年前

    我有一个控制器,允许下载任意内容类型的文件:

    @GetMapping(value="/download/{directory}/{name}",
                consumes=MediaType.ALL_VALUE)
    @Timed
    public ResponseEntity<byte[]> downloadFile(@PathVariable String directory,
                                               @PathVariable String name) {
        log.debug("REST request to download File : {}/{}", directory, name);
    
        byte[] content = "it works".getBytes();
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_TYPE, "text/plain");
        return new ResponseEntity<>(content, headers, HttpStatus.OK);
    }
    

    我想在这样的单元测试中进行测试:

    ...
    private MockMvc restFileMockMvc;
    
    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    
        final FileResource fileResource = new FileResource(fileService);
        this.restFileMockMvc = MockMvcBuilders.standaloneSetup(fileResource)
            .setCustomArgumentResolvers(pageableArgumentResolver)
            .setControllerAdvice(exceptionTranslator)
            .setConversionService(createFormattingConversionService())
            .setMessageConverters(jacksonMessageConverter)
            .setValidator(validator).build();
    }
    
    @Test
    @Transactional
    public void downloadFile() throws Exception {
        String url = "/api/download/it/works.txt";
        restFileMockMvc.perform(get(url).header(HttpHeaders.ACCEPT, "*/*"))
                       .andDo(MockMvcResultHandlers.print()) // Debugging only!
                       .andExpect(status().isOk());
    }
    

    MockMvcResultHandlers.print() 产生以下结果:

    MockHttpServletRequest:
          HTTP Method = GET
          Request URI = /api/download/DIRDIR/NAMENAME
           Parameters = {}
              Headers = {Accept=[*/*]}
                 Body = <no character encoding set>
        Session Attrs = {}
    
    Handler:
                 Type = com.example.storage.web.rest.FileResource
               Method = public org.springframework.http.ResponseEntity<byte[]> com.example.storage.web.rest.FileResource.downloadFile(java.lang.String,java.lang.String)
    
    Async:
        Async started = false
         Async result = null
    
    Resolved Exception:
                 Type = org.springframework.web.HttpMediaTypeNotAcceptableException
    
    ModelAndView:
            View name = null
                 View = null
                Model = null
    
    FlashMap:
           Attributes = null
    
    MockHttpServletResponse:
               Status = 406
        Error message = null
              Headers = {Content-Type=[application/problem+json]}
         Content type = application/problem+json
                 Body = {"type":"https://www.jhipster.tech/problem/problem-with-message","title":"Not Acceptable","status":406,"detail":"Could not find acceptable representation","path":"/api/download/DIRDIR/NAMENAME","message":"error.http.406"}
        Forwarded URL = null
       Redirected URL = null
              Cookies = []
    

    看起来该请求是与一起发送的 Accept: */* . 春天抱怨什么呢?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Narendra Pandey    7 年前

    这可能是测试用例中使用的消息转换器的问题。我也遇到了类似的问题,并通过在messageConverter中为我的mockMvc传递额外的参数来解决它

     this.restMockMvc = MockMvcBuilders.standaloneSetup(testResource)
            .setCustomArgumentResolvers(pageableArgumentResolver)
            .setControllerAdvice(exceptionTranslator)
            .setMessageConverters(jacksonMessageConverter,new 
           ByteArrayHttpMessageConverter()).build();
    

    您需要重载MockMVC的消息转换器属性。欲了解更多信息, relevant question

        2
  •  0
  •   Druckles    5 年前

    我已经在用了 @SpringJUnitWebConfig(...) 包括 @EnableWebMvc 我导入的配置的注释。这似乎增加了所有必要的转换器。例如。

    @SpringJUnitWebConfig(MyTestConfig.class)
    class MyTest {
    
      @Inject
      private WebApplicationContext wac;
    
      private MockMvc mockMvc;
      ...
    }
    
    @EnableWebMvc
    class MyTestConfig {
      @Bean
      ...
    }