How to define display name using nested attributes of arguments in ParameterizedTest(name = #{index} multiply {0[0]} x {0[1]} = {0[2]})

huangapple go评论182阅读模式
英文:

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.

  1. package net.delphym.unittests;
  2. import org.junit.jupiter.api.DisplayName;
  3. import org.junit.jupiter.params.ParameterizedTest;
  4. import org.junit.jupiter.params.provider.MethodSource;
  5. import java.util.stream.Stream;
  6. import static org.junit.jupiter.api.Assertions.assertEquals;
  7. class DynamicTestCreationTestParam {
  8. private static Stream<int[]> data() {
  9. return Stream.of(new int[][]{{1, 2, 2}, {5, 3, 15}, {121, 4, 484}});
  10. }
  11. @DisplayName("Multiplication test")
  12. @ParameterizedTest(name = "#{index} for {arguments}: {0} x {1} = {2}")
  13. @MethodSource("data")
  14. void testWithStringParameter(int[] data) {
  15. MyClass tester = new MyClass();
  16. int m1 = data[0];
  17. int m2 = data[1];
  18. int expected = data[2];
  19. assertEquals(expected, tester.multiply(m1, m2));
  20. }
  21. // class to be tested
  22. class MyClass {
  23. public int multiply(int i, int j) {
  24. return i * j;
  25. }
  26. }
  27. }

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.

  1. package net.delphym.unittests;
  2. import org.junit.jupiter.api.DisplayName;
  3. import org.junit.jupiter.params.ParameterizedTest;
  4. import org.junit.jupiter.params.provider.MethodSource;
  5. import java.util.stream.Stream;
  6. import static org.junit.jupiter.api.Assertions.assertEquals;
  7. class DynamicTestCreationTestParam {
  8. private static Stream&lt;int[]&gt; data() {
  9. return Stream.of(new int[][] { {1, 2, 2}, {5, 3, 15}, {121, 4, 484} });
  10. }
  11. @DisplayName(&quot;Multiplication test&quot;)
  12. @ParameterizedTest(name = &quot;#{index} for {arguments}: {0} x {1} = {2}&quot;)
  13. @MethodSource(&quot;data&quot;)
  14. void testWithStringParameter(int[] data) {
  15. MyClass tester = new MyClass();
  16. int m1 = data[0];
  17. int m2 = data[1];
  18. int expected = data[2];
  19. assertEquals(expected, tester.multiply(m1, m2));
  20. }
  21. // class to be tested
  22. class MyClass {
  23. public int multiply(int i, int j) {
  24. return i *j;
  25. }
  26. }
  27. }

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 = &quot;#{index} multiply : {[0][0]} x {[0][1]} = {[0][2]}&quot;
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(&quot;data&quot;) 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:

  1. private static Stream&lt;Arguments&gt; data() {
  2. return Stream.of(Arguments.of(1, 2, 2), Arguments.of(5, 3, 15), Arguments.of(121, 4, 484));
  3. }
  4. @DisplayName(&quot;Multiplication test&quot;)
  5. @ParameterizedTest(name = &quot;#{index}: {0} x {1} = {2}&quot;)
  6. @MethodSource(&quot;data&quot;)
  7. void testWithStringParameter(int m1, int m2, int expected) {
  8. MyClass tester = new MyClass();
  9. assertEquals(expected, tester.multiply(m1, m2));
  10. }

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:

  1. @DisplayName(&quot;Multiplication test&quot;)
  2. @ParameterizedTest(name = &quot;#{index} multiply: {0} x {1} = {2}&quot;)
  3. @CsvSource({&quot;1,2,2&quot;, &quot;3,5,15&quot;, &quot;121,4,484&quot;})
  4. void testWithStringParameter(int m1, int m2, int expected) {
  5. MyClass tester = new MyClass();
  6. assertEquals(expected, tester.multiply(m1, m2));
  7. }

请注意,由于代码中包含特殊字符和代码标记,因此可能无法进行完美的翻译,但我已尽力翻译了文本部分。

英文:

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(&quot;data&quot;) 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:

  1. private static Stream&lt;Arguments&gt; data() {
  2. return Stream.of(Arguments.of(1, 2, 2), Arguments.of(5, 3, 15), Arguments.of(121, 4, 484));
  3. }
  4. @DisplayName(&quot;Multiplication test&quot;)
  5. @ParameterizedTest(name = &quot;#{index}: {0} x {1} = {2}&quot;)
  6. @MethodSource(&quot;data&quot;)
  7. void testWithStringParameter(int m1, int m2, int expected) {
  8. MyClass tester = new MyClass();
  9. assertEquals(expected, tester.multiply(m1, m2));
  10. }

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:

  1. @DisplayName(&quot;Multiplication test&quot;)
  2. @ParameterizedTest(name = &quot;#{index} multiply: {0} x {1} = {2}&quot;)
  3. @CsvSource({&quot;1,2,2&quot;, &quot;3,5,15&quot;, &quot;121,4,484&quot;})
  4. void testWithStringParameter(int m1, int m2, int expected) {
  5. MyClass tester = new MyClass();
  6. assertEquals(expected, tester.multiply(m1, m2));
  7. }

huangapple
  • 本文由 发表于 2020年7月31日 14:54:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/63187101.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定