Home United States USA — software Test Parameterization With JUnit 5.7: A Deep Dive Into @EnumSource

Test Parameterization With JUnit 5.7: A Deep Dive Into @EnumSource

106
0
SHARE

@EnumSource makes an impression of an esoteric device that can hardly feel useful. Though, for the right problem, they are priceless. Find out where they shine.
Parameterized tests allow developers to efficiently test their code with a range of input values. In the realm of JUnit testing, seasoned users have long grappled with the complexities of implementing these tests. But with the release of JUnit 5.7, a new era of test parameterization enters, offering developers first-class support and enhanced capabilities. Let’s delve into the exciting possibilities that JUnit 5.7 brings to the table for parameterized testing!Parameterization Samples From JUnit 5.7 Docs
Let’s see some examples from the docs:
The @ParameterizedTest annotation has to be accompanied by one of several provided source annotations describing where to take the parameters from. The source of the parameters is often referred to as the « data provider. »
I will not dive into their detailed description here: the JUnit user guide does it better than I could, but allow me to share several observations:
The  @ValueSource is limited to providing a single parameter value only. In other words, the test method cannot have more than one argument, and the types one can use are restricted as well.
Passing multiple arguments is somewhat addressed by @CsvSource, parsing each string into a record that is then passed as arguments field-by-field. This can easily get hard to read with long strings and/or plentiful arguments. The types one can use are also restricted — more on this later.
All the sources that declare the actual values in annotations are restricted to values that are compile-time constants (limitation of Java annotations, not JUnit).
@MethodSource and @ArgumentsSource provides a stream/collection of (un-typed) n-tuples that are then passed as method arguments. Various actual types are supported to represent the sequence of n-tuples, but none of them guarantee that they will fit the method’s argument list. This kind of source requires additional methods or classes, but it provides no restriction on where and how to obtain the test data.
As you can see, the source types available range from the simple ones (simple to use, but limited in functionality) to the ultimately flexible ones that require more code to get working.
Sidenote — This is generally a sign of good design: a little code is needed for essential functionality, and adding extra complexity is justified when used to enable a more demanding use case.
What does not seem to fit this hypothetical simple-to-flexible continuum, is @EnumSource. Take a look at this non-trivial example of four parameter sets with 2 values each.
Note — While @EnumSource passes the enum’s value as a single test method parameter, conceptually, the test is parameterized by enum’s fields, that poses no restriction on the number of parameters.
Just think of it: the hardcoded list of values restricts its flexibility severely (no external or generated data), while the amount of additional code needed to declare the enum makes this quite a verbose alternative over, say, @CsvSource.
But that is just a first impression. We will see how elegant this can get when leveraging the true power of Java enums.
Sidenote: This article does not address the verification of enums that are part of your production code. Those, of course, had to be declared no matter how you choose to verify them.

Continue reading...