英文:
How to define display name using nested attributes of arguments in ParameterizedTest(name = #{index} multiply {0[0]} x {0[1]} = {0[2]})
问题
I cannot figure out if it is a missing feature, see the JUnit issue 1154 and my comment there, or just my inability to write properly the syntax for name of the @ParameterizedTest
in JUnit5. Given the fact that issue has been open for the last 3 years, I'm afraid I cannot wait till I get the answer or even the implementation there, so I'm trying to ask here as well.
In my example ParameterizedTest, I'm using @MethodSource
, which returns a Stream of int arrays, and I would like to use only those array's attributes instead of all {arguments}
, which is anyway the same if I use {0}
. Hard to explain verbally here, better to use the code example below.
package net.delphym.unittests;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
class DynamicTestCreationTestParam {
private static Stream<int[]> data() {
return Stream.of(new int[][]{{1, 2, 2}, {5, 3, 15}, {121, 4, 484}});
}
@DisplayName("Multiplication test")
@ParameterizedTest(name = "#{index} for {arguments}: {0} x {1} = {2}")
@MethodSource("data")
void testWithStringParameter(int[] data) {
MyClass tester = new MyClass();
int m1 = data[0];
int m2 = data[1];
int expected = data[2];
assertEquals(expected, tester.multiply(m1, m2));
}
// class to be tested
class MyClass {
public int multiply(int i, int j) {
return i * j;
}
}
}
The test results output looks something like this for the 1st run: #1 for [1, 2, 2]: [1, 2, 2] x {1} = {2}
Ideally, I would like to see this: #1 multiply: 1 x 2 = 2
.
So the question is, what would be the @ParameterizedTest(
name)
definition to match my expectation?
I was trying something like this:
name = "#{index} multiply : {[0][0]} x {[0][1]} = {[0][2]}"
,
But it is syntactically incorrect.
英文:
I cannot figure out if it is a missing feature, see the JUnit issue 1154 and my comment there, or just my inability to write properly the syntax for name of the @ParameterizedTest
in JUnit5. Given the fact that issue has been open for last 3 years, I'm afraid I cannot wait till I get answer or even the implementation there, so I'm trying to ask here as well.
In my example ParameterizedTest, I'm using @MethodSource
, which returns a Stream of ints arrays and I would like to use only those array's attributes instead of all {arguments}
which is anyway same if I use {0}
. Hard to explain verbally here, better to use code example bellow.
package net.delphym.unittests;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
class DynamicTestCreationTestParam {
private static Stream<int[]> data() {
return Stream.of(new int[][] { {1, 2, 2}, {5, 3, 15}, {121, 4, 484} });
}
@DisplayName("Multiplication test")
@ParameterizedTest(name = "#{index} for {arguments}: {0} x {1} = {2}")
@MethodSource("data")
void testWithStringParameter(int[] data) {
MyClass tester = new MyClass();
int m1 = data[0];
int m2 = data[1];
int expected = data[2];
assertEquals(expected, tester.multiply(m1, m2));
}
// class to be tested
class MyClass {
public int multiply(int i, int j) {
return i *j;
}
}
}
The test results output looks something like this for the 1st run: #1 for [1, 2, 2]: [1, 2, 2] x {1} = {2}
Ideally, I would like to see this: #1 multiply: 1 x 2 = 2
.
So question is what would be the @ParametrizedTest(
name)
definition to match my expectation?
I was trying something like this:
name = "#{index} multiply : {[0][0]} x {[0][1]} = {[0][2]}"
But it is syntacticly incorrect.
答案1
得分: 1
以下是您要翻译的内容:
"Alright, as suggested by @Murat Karagöz, I'm only reposting suggestions which I receive on Github to have all at one place.
In my opinion, without no doubt, those elegant solutions are only workarounds to the JUnit5 @ParameterizedTest API limitations, but they both satisfied my needs.
Proposed workaround #1 if I don't need to use int[]
Solution presented here is preserving @MethodSource("data")
and only altering its return type. Now the data()
method returns Stream of Arguments objects (3 in each), instead Stream of int arrays (of 3 in each).
Then the code reads:
private static Stream<Arguments> data() {
return Stream.of(Arguments.of(1, 2, 2), Arguments.of(5, 3, 15), Arguments.of(121, 4, 484));
}
@DisplayName("Multiplication test")
@ParameterizedTest(name = "#{index}: {0} x {1} = {2}")
@MethodSource("data")
void testWithStringParameter(int m1, int m2, int expected) {
MyClass tester = new MyClass();
assertEquals(expected, tester.multiply(m1, m2));
}
Credits goes to Marc Philipp for his post @ Github.
Proposed workaround #2 to unroll test data to match display needs##
This solution provided by sormarus suggest to use @CsvSource
instead of the @MethodSource
and provides the set of the test data within the annotation.
I like this as a simple example of how to quickly prepare the same basic variation without the need to have a specific data generating method.
The code looks like this:
@DisplayName("Multiplication test")
@ParameterizedTest(name = "#{index} multiply: {0} x {1} = {2}")
@CsvSource({"1,2,2", "3,5,15", "121,4,484"})
void testWithStringParameter(int m1, int m2, int expected) {
MyClass tester = new MyClass();
assertEquals(expected, tester.multiply(m1, m2));
}
请注意,由于代码中包含特殊字符和代码标记,因此可能无法进行完美的翻译,但我已尽力翻译了文本部分。
英文:
Alright, as suggested by @Murat Karagöz, I'm only reposting suggestions which I receive on Github to have all at one place.
In my opinion, without no doubt, those elegant solutions are only workarounds to the JUnit5 @ParameterizedTest API limitations, but they both satisfied my needs.
Proposed workaround #1 if I don't need to use int[]
Solution presented here is preserving @MethodSource("data")
and only altering its return type. Now the data()
method returns Stream of Arguments objects (3 in each), instead Stream of int arrays (of 3 in each).
Then the code reads:
private static Stream<Arguments> data() {
return Stream.of(Arguments.of(1, 2, 2), Arguments.of(5, 3, 15), Arguments.of(121, 4, 484));
}
@DisplayName("Multiplication test")
@ParameterizedTest(name = "#{index}: {0} x {1} = {2}")
@MethodSource("data")
void testWithStringParameter(int m1, int m2, int expected) {
MyClass tester = new MyClass();
assertEquals(expected, tester.multiply(m1, m2));
}
Credits goes to Marc Philipp for his post @ Github.
Proposed workaround #2 to unroll test data to match display needs##
This solution provided by sormarus suggest to use @CsvSource
instead of the @MethodSource
and provides the set of the test data within the annotation.
I like this as simple example how to quickly prepare same basic variation without a need to have a specific data generating method.
The code looks like this:
@DisplayName("Multiplication test")
@ParameterizedTest(name = "#{index} multiply: {0} x {1} = {2}")
@CsvSource({"1,2,2", "3,5,15", "121,4,484"})
void testWithStringParameter(int m1, int m2, int expected) {
MyClass tester = new MyClass();
assertEquals(expected, tester.multiply(m1, m2));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论