When developing e-commerce, one encounters numerous Enums. The following Enum represents a simple product type code. There are two types: simple options and complex options.
public enum ProductType {
SIMPLE_OPTION,
COMPLEX_OPTION
}
To test the parts that vary according to the product type, we can use @ParameterizedTest
and @EnumSource
.
@ParameterizedTest
@EnumSource(names = {"SIMPLE_OPTION", "COMPLEX_OPTION"})
void enumSourceTest(ProductType productType) {
System.out.println(productType);
}
However, it's very common for business logic to branch based on the relationships between Enums, and one may want to test those parts.
The code below represents the relationship between the product type at the product level and the item type at the item level. While there are eight possible combinations of ProductType and ItemType, only four of these combinations are actually feasible.
@Value
@Builder
public class Product {
ProductType productType;
List<Item> items;
@Value
@Builder
public static class Item {
ItemType itemType;
}
}
// The relationship between ProductType and ItemType
// SIMPLE_OPTION - SIMPLE
// COMPLEX_OPTION - COMBINATION1
// COMPLEX_OPTION - COMBINATION2
// COMPLEX_OPTION - COMBINATION3
public enum ProductType {
SIMPLE_OPTION,
COMPLEX_OPTION
}
public enum ItemType {
SIMPLE,
COMBINATION1,
COMBINATION2,
COMBINATION3,
}
Therefore, we need to set up these four combinations separately, which can be done using @ParameterizedTest
and @MethodSource
.
@ParameterizedTest
@MethodSource("productTypeAndItemTypeSet")
void methodSourceTest(ProductType productType, ItemType itemType) {
System.out.println(productType + " : " + itemType);
}
private static Stream productTypeAndItemTypeSet() {
return Stream.of(
Arguments.of(
ProductType.SIMPLE_OPTION,
ItemType.SIMPLE
),
Arguments.of(
ProductType.COMPLEX_OPTION,
ItemType.COMBINATION1
),
Arguments.of(
ProductType.COMPLEX_OPTION,
ItemType.COMBINATION2
),
Arguments.of(
ProductType.COMPLEX_OPTION,
ItemType.COMBINATION3
)
);
}
There's also a way to utilize org.junit.jupiter.api.DynamicTest
and @TestFactory
.
Let's look at the code first. It sets up the four Enum combinations with Stream.of
and then runs each through DynamicTest.dynamicTest
within a flatMap structure.
@TestFactory // It's not @Test but @TestFactory
Stream<DynamicTest> dynamicTestTest() {
return Stream.of(
Map.of(ProductType.SIMPLE_OPTION, ItemType.SIMPLE),
Map.of(ProductType.COMPLEX_OPTION, ItemType.COMBINATION1),
Map.of(ProductType.COMPLEX_OPTION, ItemType.COMBINATION2),
Map.of(ProductType.COMPLEX_OPTION, ItemType.COMBINATION3)
)
.flatMap(testCaseMap ->
testCaseMap.entrySet().stream()
.map(it ->
DynamicTest.dynamicTest(testCaseMap.toString(), () -> {
ProductType productType = it.getKey();
ItemType itemType = it.getValue();
System.out.println(productType + " : " + itemType);
}
)
)
);
}
}
Java doesn't provide a Pair class by default, so using Map made the implementation a bit complicated, requiring the use of flatMap.
Creating it with Kotlin and using Pair would indeed make it simpler.
@TestFactory
fun dynamicTestTest(): Stream<DynamicTest> {
return Stream.of(
Pair(ProductType.SIMPLE_OPTION, ItemType.SIMPLE),
Pair(ProductType.COMPLEX_OPTION, ItemType.COMBINATION1),
Pair(ProductType.COMPLEX_OPTION, ItemType.COMBINATION2),
Pair(ProductType.COMPLEX_OPTION, ItemType.COMBINATION3),
)
.map { pair ->
DynamicTest.dynamicTest(pair.toString()) {
println("${pair.first} : ${pair.second}")
}
}
}
cf) While Java doesn't provide a Pair class by default, we can use org.springframework.data.util.Pair
provided by Spring.
Top comments (0)