'junit5 MethodSource in nested class
I am working with junit5 and I want to create Parameterized Test in nested class. For example:
class CardTest {
@Nested
class Cost {
Stream<Arguments> cards() {
return Stream.of(
Arguments.of(Card.common(0, Color.RED), 0),
/** Other Data **/
Arguments.of(Card.choseColor(), 50)
);
}
@MethodSource("cards")
@ParameterizedTest
void cardCost(Card card, int cost) {
assertThat(card.cost())
.isEqualTo(cost);
}
}
/** Some other nested classes or simple methods **/
}
The problem is @MethodSource required that specified method must be static. But Java not allowed static method in non-static inner classes. If I create class Cost static then it won't be collected by junit.
What should I do to resolve this issue?
Solution 1:[1]
@TestInstance(PER_CLASS)
You may select the "single test instance per class" mode annotating the nested class with @TestInstance(TestInstance.Lifecycle.PER_CLASS):
class ColorTest {
@Nested
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class Inner {
@ParameterizedTest
@MethodSource("colors")
void blue(Color color, int blue) {
Assertions.assertEquals(color.getBlue(), blue);
}
Stream<Arguments> colors() {
return Stream.of(
Arguments.of(Color.BLACK, 0),
Arguments.of(Color.GRAY, 128),
Arguments.of(Color.BLUE, 255)
);
}
}
}
When using this mode, a new test instance will be created once per test class.
ArgumentsProvider
Or you may switch from a MethodSource to an ArgumentsProvider.
I modified your example to see if it compiles and runs locally:
class ColorTest {
static class Blues implements ArgumentsProvider {
@Override
public Stream<Arguments> provideArguments(ExtensionContext context) {
return Stream.of(
Arguments.of(Color.BLACK, 0),
Arguments.of(Color.GRAY, 128),
Arguments.of(Color.BLUE, 255)
);
}
}
@Nested
class Inner {
@ParameterizedTest
@ArgumentsSource(Blues.class)
void blue(Color color, int blue) {
Assertions.assertEquals(color.getBlue(), blue);
}
}
}
More details at http://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests
Solution 2:[2]
Another variation based on JUnit 5.2.0 is this.
class ColorTest {
public static Stream<Arguments> provideColors() {
return Stream.of(
Arguments.of(Color.BLACK, 0),
Arguments.of(Color.GRAY, 128),
Arguments.of(Color.BLUE, 255)
);
}
@Nested
class Inner {
@ParameterizedTest
@MethodSource("com.domain.ColorTest#provideColors")
void blue(Color color, int blue) {
Assertions.assertEquals(color.getBlue(), blue);
}
}
}
Solution 3:[3]
A bit late to this game, but...
You can implement the provider, as a static, in the outer class. Then, in @MethodSource, you simply need to provide the fully qualified name of the parameter (i.e., com.biz.pckg#colors).
This is documented in the JUnit user guide.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | jpenna |
