/puma4j

Easy and convenient way to load file resources into your tests using only annotations.

Primary LanguageJavaMIT LicenseMIT

Puma4j

Repository Logo
Easy and convenient way to load file resources into your tests using only annotations.

GitHub Action Status Codecov Badge Conventional Commits Sonar Quality Gate Status Sonatype Nexus (Releases)

Overview

Puma4j provides a convenient and easier way to load and parse file resources in your JUnit 5 tests using just a couple of annotations :)

Installation

Java 8

Using Gradle:

testImplementation "io.github.vitorsalgado.puma4j:puma4j-junit5-extension:4.0.4"

or Maven:

<dependency>
  <groupId>io.github.vitorsalgado.puma4j</groupId>
  <artifactId>puma4j-junit5-extension</artifactId>
  <version>4.0.4</version>
  <scope>test</scope>
</dependency>

How It Works

Puma4j, when enabled, detects fields or parameters annotated with @Res and inject resource values based on annotated element type, resource extension and any custom unmarshaller added.
You can use String and byte[] for all types of resources.
Puma4j is also able to convert some resource types to object type representations:

  • Json: Object types based on the json structure. It uses Jackson ObjectMapper and Gson. Defaults to Jackson ObjectMapper
  • Yaml: Object types based on yaml structure. It uses Jackson ObjectMapper.
  • Properties: Converts .properties files to java Properties class.

For custom object conversions use a custom unmarshaller using the annotation @Use, passing the class type of your custom unmarshaller implementation.

Usage

First, annotate your JUnit 5 test classes with @UsePuma4j. Now you can use the annotation @Res to inject resources on class fields and/or method parameters.
Take a look on the complete example below:

@UsePuma4j
class UsageWithJUnit5 {

  @Res("data.txt")
  private static String staticTextData;

  @Res("complex.json")
  private List<ComplexModel> complexModelList;

  @Res("complex-yml.yaml")
  private List<ComplexModel> complexModelListFromYaml;

  @Res("test.properties")
  private Properties testProperties;

  @Res("simple.json")
  @Use(JsonTreeUnmarshaller.class)
  private JsonNode simpleJsonTree;

  @Test
  void simpleTest(final @Res("simple.json") SimpleModel model) {
    assertEquals(50, model.getAge());
    assertEquals("no-one", model.getName());
  }

  public static class JsonTreeUnmarshaller implements Unmarshaller<JsonNode> {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @Override
    public JsonNode unmarshal(final Args args) throws IOException {
      return OBJECT_MAPPER.readTree(args.getInput());
    }
  }
}

Features

Forcing Jackson or Gson

For json files, the default parser is Jackson ObjectMapper. If you want to use Gson for a specific type use: @UseGson. If applied in the class level, all json conversions will use Gson. You can use @UseJackson to keep using Object Mapper on specific resources.

Custom Unmarshaller

You can use your custom unmarshaller implementation.
First, create a new class implementing the interface Unmarshaller<O>.
Then, use the annotation @Use(YourCustomUnmarshaller.class) on the class, field or method level to use your new custom unmarshaller.

Kotlin Delegate

You can load resources using a Kotlin delegate also. Look the example below:

private val simpleModel: SimpleModel by res("simple.json")

To use the delegate res, add the library below to your project:

testImplementation "io.github.vitorsalgado.puma4j:puma4j-kotlin:4.0.4"

Contributing

See CONTRIBUTING for more details.

Contributors

Thanks goes to these wonderful people ✨:


Sebastián Muñoz Eyquem

This project follows the all-contributors specification. Contributions of any kind welcome!

License

This project is MIT Licensed.