我正在尝试在控制器上测试以下 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
但无能为力。
您面临的问题与使用
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
问题。