我应该如何使用多部分文件作为RequestParam来测试这个Java API

问题描述 投票:0回答:1

我正在尝试在控制器上测试以下 API:

@PostMapping("/{code}")
public ResponseEntity<RefInterneImportDTO> importFichier(@PathVariable("code") String code,
                                                         @RequestParam("file") MultipartFile file) {
    return ResponseEntity.ok(refInterneImportService.importFichier(code, file));
}

我正在尝试通过 Cucumber/JUnit 测试这个 API

 @Quand("On appelle refInterneImportController.importer pour importer un fichier {string}")
public void On_appelle_refinterne_import_controller_importer_pour_importer_un_fichier(String nomFichier) {
    try {
        file = new MockMultipartFile(nomFichier, nomFichier, "multipart/form-data",
            new FileInputStream("src/test/resources/templates/" + nomFichier));
    } catch (IOException e) {
        Assert.fail();
    }
    String urlTemplate = UriComponentsBuilder.fromHttpUrl(URL_REF_INTERNE_IMPORT).path("/" + dto.code()).toUriString();
    REST_TEMPLATE.postForObject(urlTemplate, file, RefInterneImportDTO.class);
}

但是,每当我通过 REST_TEMPLATE 调用 API 时,我都会得到:

org.springframework.http.converter.HttpMessageConversionException:类型定义错误:[简单类型,类 java.io.ByteArrayInputStream]
导致:com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
找不到类 java.io.ByteArrayInputStream 的序列化器,也没有发现创建 BeanSerializer 的属性(为避免异常,禁用 SerializationFeature.FAIL_ON_EMPTY_BEANS)(通过引用链:org.springframework.mock.web.MockMultipartFile["inputStream"])

我已经尝试禁用此序列化功能,但没有任何反应。我知道有些人可能会建议更改我的 API 签名以接受字节数组而不是

MultipartFile
,但是,发送字节数组并不比
MultipartFile
更安全。 我也尝试过构建自定义
HttpEntity
但无能为力。

java unit-testing model-view-controller junit
1个回答
0
投票

您面临的问题与使用

serialization
发出请求时
MockMultipartFile
对象的
REST_TEMPLATE
有关。
MockMultipartFile
不正确,导致上述异常。
要解决此问题,您可以尝试直接使用 

serialized

RestTemplate
来构造请求。以下是如何修改测试方法的示例:
MultiValueMap

此方法手动构造表单数据的 
@Quand("On appelle refInterneImportController.importer pour importer un fichier {string}") public void On_appelle_refinterne_import_controller_importer_pour_importer_un_fichier(String nomFichier) { try { // Load the file into a byte array byte[] fileContent = Files.readAllBytes(Paths.get("src/test/resources/templates/" + nomFichier)); // Create a MultiValueMap to represent the form data MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>(); parts.add("file", new HttpEntity<>(fileContent)); // Set up the headers HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); // Create the request entity HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(parts, headers); // Construct the URL String urlTemplate = UriComponentsBuilder.fromHttpUrl(URL_REF_INTERNE_IMPORT).path("/" + dto.code()).toUriString(); // Make the request using RestTemplate ResponseEntity<RefInterneImportDTO> responseEntity = new RestTemplate().exchange( urlTemplate, HttpMethod.POST, requestEntity, RefInterneImportDTO.class ); // Handle the response as needed // ... } catch (IOException e) { e.printStackTrace(); Assert.fail(); } }

并使用

MultiValueMap
发出请求。这样,您可以更好地控制请求,并可以避免与
RestTemplate.exchange
相关的
serialization
问题。
    

© www.soinside.com 2019 - 2024. All rights reserved.