Test unitario subida de archivos - Spring webflux

Ejemplo de subida de archivos en Spring webflux y test unitarios.

Cuando esta trabajando con Sprint webflux , necesitas subir archivos a tu aplicación puedes usar los BodyExtractors.toMultipartData() , lo cuales te permitirán obtener los archivos enviados por la api y con una función puedes extraer  los byte[] de un archivo de tipo FilePart.

Ejemplo :

 private  Mono<data> getFile(ServerRequest serverRequest){
        return serverRequest.body(BodyExtractors.toMultipartData())
                .flatMap(parts -> {
                    Map<String, Part> part = parts.toSingleValueMap();
                    return Mono.just((FilePart) part.get("file"));
                })
                .flatMap(filePart -> {
                    Mono<byte[]> dataStreamFile =      validateContent(filePart.content());
                    
                    return  dataStreamFile;
                })
                .flatMap(data );
    }
    
       private Mono<byte[]> validateContent(Flux<DataBuffer> file) {
        return file.single().map(dataBuffer -> {
            if (dataBuffer.readableByteCount() <= ZERO) {
                throw new IllegalArgumentException("error no records were found in the file");
            }
            if (dataBuffer.readableByteCount() > MAX_FILE_SIZE) {
                throw new IllegalArgumentException("error while loading file, exceeds the allowed upload capacity");
            }
            byte[] bytes = new byte[dataBuffer.readableByteCount()];
            dataBuffer.read(bytes);
            return bytes;
        }).onErrorMap(throwable -> new RuntimeException("Error process file content"));
    }

Para los test unitarios, puedes importar el archivo en byte[] y lo asignas al MultipartBodyBuilder , con el nombre del  Part que vas a extraer en tu función.

Ejemplo:

MultipartBodyBuilder builder  = new MultipartBodyBuilder();
        builder.part("file", bytes,MediaType.MULTIPART_FORM_DATA)
                .header("Content-Disposition", "form-data; name=file; filename=prueba.xlsx");     

y despues se lo asignas al body de tu test unitario.

Ejemplo.


    WebTestClient webTestClient;
   @Test
    void validateMultiple() throws URISyntaxException, IOException {

        byte[] bytes = Files.readAllBytes(Paths.get(getClass().getClassLoader()
                .getResource("prueba.xlsx").toURI()));

        MultipartBodyBuilder builder  = new MultipartBodyBuilder();
        builder.part("file", bytes,MediaType.MULTIPART_FORM_DATA)
                .header("Content-Disposition", "form-data; name=file; filename=prueba.xlsx");

      
        webTestClient.post().uri(uriBuilder -> uriBuilder
                        .path(BASE_ROUTE+ "/upload")
                        .build())
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .body(BodyInserters.fromMultipartData(builder.build()))
                .exchange()
                .expectStatus()
                .isOk();
    }

happy code :).

Referencias:

https://www.javadoc.io/doc/org.springframework/spring-web/5.0.3.RELEASE/org/springframework/http/client/MultipartBodyBuilder.html