Argument Conversion in Parameterized Tests in Junit 5

By | October 4, 2020

In this post, We will talk and learn about  Implicit and explicit Argument Conversion in ParameterizedTest Tests in JUnit Jupiter

  • Widening Conversion

JUnit Jupiter supports Widening Primitive Conversion for arguments specified to a @ParameterizedTest. For example,  if a parameterized test annotated with @ValueSource(ints = { 1, 2, 3 }) can be declared to accept not only an argument of type int but also an argument of type longfloat, or double.

  • Implicit Conversion

    To support use cases like @CsvSource, JUnit Jupiter provides a number of built-in implicit type converters. Usually, the conversion process basically depends on the declared type of each method argument.

    For example, if a @ParameterizedTest declares a parameter of type TimeUnit and the actual type supplied by the declared source is a String, the string will be automatically converted into the corresponding TimeUnit enum constant.

     

  • Fallback String-to-Object Conversion

    In addition to implicit conversion from strings to the target types listed in the above table, JUnit Jupiter also provides a fallback mechanism for automatic conversion from a String to a given targetType if the targetType declares exactly one suitable factory method or a factory constructor.

    • factory method: a non-private, static a method declared in the target type that accepts a single argument and returns an instance of the target type. The name of the method can be anything and need not follow any particular convention method.
    • factory constructor: a non-private constructor in the target type that accepts a single argument. You should also note that the targetType should be declared as either a top-level class or as a static inner class. 
    If multiple factory methods found then they will be ignored. If a factory method and a factory constructor are discovered, the factory method will be used instead of the constructor.

    For example, in the following @ParameterizedTest method, the Book the argument will be created by invoking the Book.fromTitle(String) factory method and passing "Hibernate Compelete Reference" as the title of the book.

     

    Explicit Conversion

  • Instead of relying on implicit argument conversion, you may explicitly specify an ArgumentConverter to use for a certain parameter using the @ConvertWith annotation like in the following example. You should note that an implementation of ArgumentConverter must be declared as either a top-level class or as a static inner class.

Let’s say converter is only meant to convert one type to another then you can extend TypedArgumentConverter to avoid boilerplate type checks. 

The explicit argument converters are meant to be implemented by test and extension developer so junit-jupiter-params only provides a single explicit argument converter that may be used as a reference implementation: JavaTimeArgumentConverter. It is used via the composed annotation JavaTimeConversionPattern

Let’s try to understand the above concept using a demo project

pom.xml

MyUtils.java 

Book.java

Employee.java

EmployeeType.java

StringArgumentConverter.java

ExplicitConversionTest.java

 

MyUtilsTest.java

The output of the above project:

 

You May Also Like:

Junit 5 Architecture
JUnit 5 Annotations
JUnit 5 Maven Dependency
JUnit 5 with Gradle Dependency
JUnit 5 Test Lifecycle
JUnit 5 @BeforeAll annotation example
Unit 5 @AfterAll annotation example
JUnit 5 @BeforeEach and @AfterEach annotation Example
JUnit 5 Display Names
Assertions in JUnit 5 Examples
Third-party Assertion Libraries support in JUnit 5
JUnit 5 Assumptions Examples
Conditional Test Execution in JUnit 5
JUnit 5 Nested Tests Example
JUnit 5 @Tag Annotation example
Test Execution Order in Junit 5
Dependency Injection and Testing in JUnit 5
Test Interfaces and Default Methods in JUnit 5

That’s all about Argument Conversion in Parameterized Tests in Junit 5
If you have any feedback or suggestion please feel free to drop in below comment box.

Leave a Reply

Your email address will not be published.