错误请求错误单元测试多部分弹簧休息

时间:2017-04-20 08:44:17

标签: java spring rest unit-testing spring-boot

我有下一个单元测试定义来测试用于上传文件的控制器:

 public class PhenotypeControllerTest extends BaseControllerTest{

        private MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
                MediaType.APPLICATION_JSON.getSubtype(),
                Charset.forName("utf8"));

        @Before
        public void setup() throws Exception {
            super.setup();
        }

        @Test
        public void loadPhenotype_success() throws Exception{
            //mock uuid generation
            UUID idFile = UUID.randomUUID();
             //Generate the response
             ResponseLoad resp = new ResponseLoad();
             resp.setFileIdentifier(idFile);
             resp.setStatus(Status.FINISHED);
             resp.setDescription(null);

             MockMultipartFile phenoFile  = new MockMultipartFile("size_trans_20160419_KM2.txt","size_trans_20160419_KM2.txt", ContentType.TEXT_PLAIN.toString(), new FileInputStream("src/test/resources/size_trans_20160419_KM2.txt"));
             mockMvc.perform(MockMvcRequestBuilders.fileUpload("/phenotypes/load")
                                    .file(phenoFile))
                                    .andExpect(status().isOk())
                                    .andExpect(content().contentType(this.contentType))
                                    .andExpect(content().json(json(resp)));
        }
    }

测试的超类包含注释:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@WebAppConfiguration
@TestPropertySource(locations="classpath:application.test.properties")
public abstract class BaseControllerTest {

    protected MockMvc mockMvc;

    @SuppressWarnings("rawtypes")
    protected HttpMessageConverter mappingJackson2HttpMessageConverter;

    @Autowired
    protected WebApplicationContext webApplicationContext;

     @Autowired
    void setConverters(HttpMessageConverter<?>[] converters) {

        this.mappingJackson2HttpMessageConverter = Arrays.asList(converters).stream()
            .filter(hmc -> hmc instanceof MappingJackson2HttpMessageConverter)
            .findAny()
            .orElse(null);

        assertNotNull("the JSON message converter must not be null",
                this.mappingJackson2HttpMessageConverter);
     }

     public void setup() throws Exception {
            this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
     }

     @SuppressWarnings("unchecked")
    protected String json(Object o) throws IOException {
        MockHttpOutputMessage mockHttpOutputMessage = new MockHttpOutputMessage();
        this.mappingJackson2HttpMessageConverter.write(
                o, MediaType.APPLICATION_JSON, mockHttpOutputMessage);
        return mockHttpOutputMessage.getBodyAsString();
    }
}

当我运行测试时,我得到400错误,但使用非多部分请求的其他测试工作正常。控制器方法如下:

@ApiOperation(value = "Load Phenotype File", nickname = "loadPhenotype",
        tags = {"Phenotypes"} )
        @ApiResponses({
            @ApiResponse(code = 200, message = "Nice!", response = Response.class),
            @ApiResponse(code = 507, message = "Error uploading files")
        })
@PostMapping(value="/phenotypes/load", produces = "application/json")
public ResponseEntity<ResponseLoad> uploadPhenotype(
        @ApiParam(value="Phenotype File", required=true) 
        @RequestPart(required = true) MultipartFile file){
    //1. Validate parameters
    ResponseLoad response = new ResponseLoad();
    response.setStatus(Status.FINISHED);
    //2. Copy file to /tmp/SNPaware/phenotypes/tmp/<UUID>.pheno
    response.setFileIdentifier(UUID.randomUUID());
    logger.info("Storage phenotype file with identifier "+response.getFileIdentifier());
    storageService.store(file, "tmp/"+response.getFileIdentifier()+".pheno");

    return ResponseEntity.ok(response);
}

}

当我向其他api发送请求时,它正常工作:

  

curl -X POST --header&#39; Content-Type:multipart / form-data&#39; --header   &#39;接受:application / json&#39; {&#34;类型&#34;:&#34; FORMDATA&#34;}   &#39; http://hippo:9087/phenotypes/load&#39;

为什么我在测试中收到400?我在测试中缺少一些配置吗?

1 个答案:

答案 0 :(得分:1)

问题在于测试中multipartFile的定义。原始名称应与控制器中参数的名称匹配,在本例中为文件。

这个定义解决了这个问题:

IF OBJECT_ID('[dbo].[usp_AttendanceDelete]') IS NOT NULL
BEGIN 
    DROP PROCEDURE [dbo].[usp_AttendanceDelete] 
END 
GO
CREATE PROCEDURE [dbo].[usp_AttendanceDelete] 
@A_ID int,
@msg        VARCHAR(50) OUTPUT,
@return     INT     OUTPUT

AS 
BEGIN
    SET NOCOUNT ON 
    BEGIN TRANSACTION
        BEGIN TRY

    DELETE
    FROM   [dbo].[Attendance]
    WHERE  [A_ID] = @A_ID

                   SET @msg = 'Attendance Deleted'
                   SET @return = 1
        END TRY
        BEGIN CATCH
        --SELECT error_message() as error
            SET @msg = 'Attendance Delete FAIL.'
            SET @return = 0
            GOTO fail_rollback
        END CATCH
    COMMIT TRANSACTION
    RETURN
fail_rollback:
    ROLLBACK TRANSACTION
    RETURN
END
GO