Search code examples
javatestingquarkusmultipartfile

Test Quarkus endpoint with multipart file upload with RestAssured


I want to send files to an endpoint. These files should then be stored on a given path.

To implement this, I wrote the following endpoint:

    @Path("upload")
    @PUT
    public void uploadTagFile(@RestForm("tagFile") FileUpload tagFile, @HeaderParam("sessionId") UUID sessionId) {
        Session session = sessionService.obtainActiveSession(sessionId);

        File copied;
        try {
            copied = Files.copy(tagFile.uploadedFile(), java.nio.file.Path.of(storageDirectory + "/sessions/" + tagFile.fileName())).toFile();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        tagFilesService.addTagFile(session, copied);
    }

I thought this should be fine and went ahead and wrote a test for this endpoint that uploads a file which is located in the resources of the test module:

    @Test
    public void uploadTagFile_ValidSessionWithFile_UploadSuccessful() {
        //Setup
        File file = ResourceUtils.getResourceAsFile("sampledata/tag/unitdata.tag");
        Assertions.assertNotNull(file);

        //Action + Assert
        given().header("sessionId", sessionId)
                .header(new Header("content-type", "multipart/form-data"))
                .multiPart("tagFile", file)
                .contentType("multipart/form-data")
                .when()
                .put("/api/tag/upload")
                .then()
                .statusCode(204);
    }

This gave me the following error message;

2023-11-07 16:15:27,918 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (executor-thread-1) HTTP Request to /api/tag/upload failed, error id: 2dc30e07-b49c-4155-817a-3599e53af9b5-1: java.lang.RuntimeException: java.nio.file.NoSuchFileException: C:\Users\XXX\AppData\Local\Temp\uploads\resteasy-reactive5082349700154976184upload -> tmpstorage\sessions\7577918012706382072813560817.tmp
    at com.xxx.tpu.quarkus.tag.TagFilesController.uploadTagFile(TagFilesController.java:40)
    at com.xxx.tpu.quarkus.tag.TagFilesController$quarkusrestinvoker$uploadTagFile_f34cf665f31482fa40b85501ce781413d7f28f10.invoke(Unknown Source)
    at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
    at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
    at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
    at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:582)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
    at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
    at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.nio.file.NoSuchFileException: C:\Users\XXX\AppData\Local\Temp\uploads\resteasy-reactive5082349700154976184upload -> tmpstorage\sessions\7577918012706382072813560817.tmp
    at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
    at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
    at java.base/sun.nio.fs.WindowsFileCopy.copy(WindowsFileCopy.java:202)
    at java.base/sun.nio.fs.WindowsFileSystemProvider.copy(WindowsFileSystemProvider.java:283)
    at java.base/java.nio.file.Files.copy(Files.java:1295)
    at com.xxx.tpu.quarkus.tag.TagFilesController.uploadTagFile(TagFilesController.java:38)
    ... 11 more

Therefore I set a breakpoint in my controller method and got this from my debugger:

enter image description here

I don't understand what is wrong and why my fileUpload is not containing my file. What am I doing wrong here?

You can find a minimal reproducible example here: https://github.com/LocutusV0nB0rg/QuarkusFileUpload/tree/master

EDIT:

I dug a bit more and it seems the file is being transmitted correctly. However, I cannot access it.

enter image description here

This file does contain the data of the file I transmitted in the test, I just cannot access it. So I guess the test is written correctly, but the endpoint has to access the file in some different way


Solution

  • The file upload works correctly - if you do tagFile.uploadedFile().toFile().exists() you will see the value is true.

    The problem is that you are copying the file to a directory that does not exist