使用字符串数组参数运行参数化 JUnit 测试失败
Rerunning parametrized JUnit test with string array parameter fails
在 Eclipse 中使用 parametrized JUnit tests 时,我 运行 在想重新 运行 单个测试时遇到了问题。测试本身 运行 很好,而我 可以 从上下文菜单重新 运行 第一个测试,重新 运行 第二个测试:
失败并显示以下消息:
java.lang.Exception: No tests found matching [{ExactMatcher:fDisplayName=test[1: A2 --> [Ljava.lang.String;@1e4a7dd4]], {ExactMatcher:fDisplayName=test[1: A2 --> Ljava.lang.String;@1e4a7dd4]] from org.junit.internal.requests.ClassRequest@6c3f5566
我很确定这是因为 JUnit 没有 'like' 我的数组;对于某些上下文:我用它来解释由于外部环境,被测代码可以为特定测试用例产生两种结果之一的事实。
下面是一些重现此代码的代码:
package com.stackexchange.toolbox;
import java.util.ArrayList;
import java.util.Arrays;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class Tester {
public Tester(String source, Object target) {
this.source = source;
this.target = target;
}
private final String source;
private final Object target;
private static final Object[][] testCases = { { "A1", "B1" }, { "A2", new String[] { "B2", "C2" } } };
@Parameters(name = "{index}: {0} --> {1}")
public static Iterable<Object[]> data() throws Exception {
return new ArrayList<>(Arrays.asList(testCases));
}
@Test
public void test() throws Exception {
if (target instanceof String) {
Assert.assertEquals(source.charAt(1), ((String)target).charAt(1));
} else {
for (String target : (String[])this.target) {
Assert.assertEquals(source.charAt(1), target.charAt(1));
}
}
}
}
有没有一种简单的方法可以解决这个问题,也许使用 List
s 或可变参数?大多数(100+)测试用例都是简单的'source'、'target'条目,我想保持{ "A1", "B1" }
.
的简洁
这似乎是 JUnit4 的限制 (at least you get the same error on the command line)。
最简单直接的解决方案是从 JUnit4迁移到 JUnit5,这也意味着更少的代码:
package com.stackexchange.toolbox;
import java.util.Arrays;
import java.util.stream.Stream;
import org.junit.Assert;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class Tester {
private static final Object[][] testCases = { { "A1", "B1" }, { "A2", new String[] { "B2", "C2" } } };
@ParameterizedTest(name = "{index}: {0} --> {1}")
@MethodSource("provideArguments")
void test(String source, Object target) {
if (target instanceof String) {
Assert.assertEquals(source.charAt(1), ((String)target).charAt(1));
} else {
for (String targetElement : (String[])target) {
Assert.assertEquals(source.charAt(1), targetElement.charAt(1));
}
}
}
static Stream<? extends Arguments> provideArguments() throws Exception {
return Arrays.stream(testCases).map(Arguments::of);
}
}
在 Eclipse 中使用 parametrized JUnit tests 时,我 运行 在想重新 运行 单个测试时遇到了问题。测试本身 运行 很好,而我 可以 从上下文菜单重新 运行 第一个测试,重新 运行 第二个测试:
失败并显示以下消息:
java.lang.Exception: No tests found matching [{ExactMatcher:fDisplayName=test[1: A2 --> [Ljava.lang.String;@1e4a7dd4]], {ExactMatcher:fDisplayName=test[1: A2 --> Ljava.lang.String;@1e4a7dd4]] from org.junit.internal.requests.ClassRequest@6c3f5566
我很确定这是因为 JUnit 没有 'like' 我的数组;对于某些上下文:我用它来解释由于外部环境,被测代码可以为特定测试用例产生两种结果之一的事实。
下面是一些重现此代码的代码:
package com.stackexchange.toolbox;
import java.util.ArrayList;
import java.util.Arrays;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class Tester {
public Tester(String source, Object target) {
this.source = source;
this.target = target;
}
private final String source;
private final Object target;
private static final Object[][] testCases = { { "A1", "B1" }, { "A2", new String[] { "B2", "C2" } } };
@Parameters(name = "{index}: {0} --> {1}")
public static Iterable<Object[]> data() throws Exception {
return new ArrayList<>(Arrays.asList(testCases));
}
@Test
public void test() throws Exception {
if (target instanceof String) {
Assert.assertEquals(source.charAt(1), ((String)target).charAt(1));
} else {
for (String target : (String[])this.target) {
Assert.assertEquals(source.charAt(1), target.charAt(1));
}
}
}
}
有没有一种简单的方法可以解决这个问题,也许使用 List
s 或可变参数?大多数(100+)测试用例都是简单的'source'、'target'条目,我想保持{ "A1", "B1" }
.
这似乎是 JUnit4 的限制 (at least you get the same error on the command line)。
最简单直接的解决方案是从 JUnit4迁移到 JUnit5,这也意味着更少的代码:
package com.stackexchange.toolbox;
import java.util.Arrays;
import java.util.stream.Stream;
import org.junit.Assert;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class Tester {
private static final Object[][] testCases = { { "A1", "B1" }, { "A2", new String[] { "B2", "C2" } } };
@ParameterizedTest(name = "{index}: {0} --> {1}")
@MethodSource("provideArguments")
void test(String source, Object target) {
if (target instanceof String) {
Assert.assertEquals(source.charAt(1), ((String)target).charAt(1));
} else {
for (String targetElement : (String[])target) {
Assert.assertEquals(source.charAt(1), targetElement.charAt(1));
}
}
}
static Stream<? extends Arguments> provideArguments() throws Exception {
return Arrays.stream(testCases).map(Arguments::of);
}
}