How to pass resource bytes as parameters

143 Views Asked by At

I have a Test method foo. I have test input large.zst in test/resources. Now I would like to pass the bytes of large.zst as byte[] into foo.

Is there any way of passing the file content as a byte array via Annotations?

3

There are 3 best solutions below

0
abergmeier On BEST ANSWER

Adapting the answer from @tquadrat to testng would look like this IMO:

    @DataProvider(name = "largeCompressed")
    private Object[] createLargeCompressed() {
        // Had no luck using `new Path`.
        URL url = this.getClass().getResource("/large.zst");
        Path path;
        try {
            path = Path.of(url.toURI());
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
        try {
            return new Object[]{Files.readAllBytes(path)};
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Test(dataProvider = "largeCompressed")
    public void foo(byte[] largeCompressed) {
        // do something with the byte array …
    }
1
tquadrat On

I do not know how to do this for TestNG, but with JUnit, I would abuse a value source and implement an ArgumentProvider.

public class LargeZSTAsBytesArgumentsProvider implements ArgumentsProvider 
{
  @Override
  public final Stream<? extends Arguments> provideArguments( ExtensionContext context ) 
  {
    final var path = Paths.get( ".", "test", "resources", "large.zst" );
    final var bytes = Files.readAllBytes( path );

    final var retValue = Stream.of( Arguments.of( bytes ) );
    return retValue;
  }
}

Basically, you get the file as an instance of java.nio.Path, then you call Files::readAllBytes with that Path instance and wraps the resulting byte array.

foo() will then look like this:

@ParameterizedTest
@ArgumentsSource( LargeZSTAsBytesArgumentsProvider.class )
void foo( final byte [] input ) 
{
  // do something with the byte array …
}

Obviously, the error handling is missing!

0
Shant Khayalian On

To pass the bytes of a file (e.g., "large.zst" located in test/resources) as a parameter to a test method using annotations in JUnit 5, you can use the @ParameterizedTest annotation along with @MethodSource. Here's an example of how to do this:

First, create a method that provides the test data. In this case, it will read the file and return its contents as a byte array.

Annotate this method with @MethodSource to specify it as the source of test data.

In your test method, accept the byte array as a parameter.

Here's an example:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class MyTest {

    @ParameterizedTest
    @MethodSource("provideFileContents")
    void testFoo(byte[] fileContent) {
        // Now you can use the fileContent byte array in your test method
        // ... your test logic here ...
    }

    // This method reads the file and provides its content as a byte array
    static byte[][] provideFileContents() throws IOException {
        Path filePath = Path.of("src/test/resources/large.zst");
        byte[] fileContent = Files.readAllBytes(filePath);
        return new byte[][] { fileContent };
    }
}

The provideFileContents method reads the content of the "large.zst" file and returns it as a two-dimensional byte array.

The @ParameterizedTest annotation is used on the test method, and @MethodSource("provideFileContents") specifies that the test data will come from the provideFileContents method.

Inside the testFoo method, you can use the fileContent byte array for testing your logic.

This approach allows you to pass resource bytes as parameters to your test method using annotations in JUnit 5.

Also I am not sure if this is what you are looking for.