es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

No se pudo obtener la entidad de respuesta de una API con MockMvc.

Tengo un problema cuando intento ejecutar la clase de prueba unitaria del controlador. Siempre obtengo un cuerpo vacío en la respuesta y no logro encontrar el motivo. Adjunto aquí el código. Quizá alguien con una visión externa pueda ver la razón.

El controlador:

@ResponseBody
@PostMapping(path = "/upload", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<object> uploadFile(@RequestParam("file") MultipartFile multipartFileData, @RequestParam(name="jobId", required = false) String jobId) {
    JobStatus result;
    try {
        result = this.fileService.uploadFileChunk(multipartFileData, 1, 1, jobId);
    }catch (ExecutionException|InterruptedException|IOException ex){
        Thread.currentThread().interrupt();
        return new ResponseEntity<>(ex,HttpStatus.INTERNAL_SERVER_ERROR);
    }
    return new ResponseEntity<>(result,HttpStatus.OK);
}

La clase de prueba unitaria:

@RunWith(SpringRunner.class)
@SpringBootTest(classes= FileUploadServiceRestController.class)
public class FileUploadServiceControllerTest {

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext context;

    @MockBean
    private FileUploadServiceImpl fileService;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
    }

    @Test
    public void testUploadFile()
            throws Exception {
        MockMultipartFile file = new MockMultipartFile(
                "file",
                "hello.txt",
                MediaType.TEXT_PLAIN_VALUE,
                "Hello, World!".getBytes()
        );

        JobStatus job = new JobStatus("uuid", ConstantUtil.JOB_STARTED);
        when(fileService.uploadFileChunk(Mockito.any(MultipartFile.class),Mockito.eq(1),Mockito.eq(1),Mockito.isNull())).thenReturn(job);
        mockMvc.perform(MockMvcRequestBuilders.multipart("/file/upload").file(file))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(status().isOk());
    }
}

El objeto que se transferirá:

public class JobStatus implements Serializable {
    private static final long serialVersionUID = -4405865740177389860L;
    private String jobId;

    private String status;

    public JobStatus() {
    }

    public JobStatus(String jobId, String status) {
        this.jobId = jobId;
        this.status = status;
    }

    public String getJobId() {
        return jobId;
    }

    public void setJobId(String jobId) {
        this.jobId = jobId;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}

Para información, este controlador funciona bien cuando lo llamo desde el cliente. Puedo ver que el mock se devuelve correctamente cuando pongo un punto de interrupción al final del controlador, pero el cuerpo de la respuesta sigue vacío.

Añado aquí el resultado de la impresión por si pudiera ayudar:

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /file/upload
       Parameters = {}
          Headers = [Content-Type:"multipart/form-data"]
             Body = <no character="" encoding="" set="">
    Session Attrs = {}

Handler:
             Type = org.iso.fileservice.controller.FileUploadServiceRestController
           Method = org.iso.fileservice.controller.FileUploadServiceRestController#uploadFile(MultipartFile, String)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = org.springframework.http.converter.HttpMessageNotWritableException

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 500
    Error message = null
          Headers = []
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

Gracias, Mathieu

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema parece estar en que el cuerpo de respuesta está vacío en la clase de prueba de unidad del controlador. Aquí hay algunas cosas que puede intentar para resolver el problema:

    1. Verifique si @PostMapping está funcionando correctamente y si las restricciones se están cumpliendo correctamente. Puede intentar llamar al punto final de la API utilizando cualquier cliente de API REST como Postman o curl y verificar si el cuerpo de la respuesta se devuelve correctamente.
    2. Verifique si el objeto simulado se devuelve correctamente por la clase FileUploadServiceImpl.

    3. Verifique si el objeto JobStatus se está serializando correctamente en el cuerpo de respuesta. Puede intentar agregar un punto de interrupción en el punto donde se crea el objeto de respuesta y verificar si los valores se están configurando correctamente.

    4. También puede intentar cambiar el tipo de retorno del método uploadFile a String (en lugar de ResponseEntity) y devolver una versión JSON con formato de cadena de JobStatus en el cuerpo de respuesta. Esto puede ayudar a identificar si el problema está en ResponseEntity.

    Pruebe estos pasos y vea cuál resuelve el problema. ¡Buena suerte!

Comments are closed.