JUnit - 分享不同实现的测试
JUnit - Share Tests Of Different Implementations
我正在寻找最易读的方式来共享接口不同实现的测试。
关于这个主题的最受欢迎但相当古老的问题是 -
Writing a single unit test for multiple implementations of an interface.
针对上述问题,给出了 2 个主要和不同的答案 -
- 参数化测试。
- 测试继承。
我对这两个答案都不满意。
参数化测试 - 答案不包括如何对每个子类进行参数化的代码示例。另外,我个人很难进行参数化测试,我发现 API 一点也不直观。
我总是害怕过度使用继承,而且我不确定测试继承是否是一个好的做法。
想知道2018年这个问题的最佳答案是什么
可能不是最像 Java 的,但您可以遵循 table 驱动的测试格式。使用本地 class,以保持测试的可读性,并使上下文尽可能接近真实测试。
注意:这与 @RunWith(Parameterized.class)
的底层高级方法非常相似
// Assuming Animal interface has a `public boolean canDance()`
@Test
public void TestAnimalCanDance() {
class Tester {
String errMsgFmt = "%s failed the test";
boolean expected;
Animal animal;
public Tester(boolean expected, Animal animal) {
this.expected = expected;
this.animal = animal;
}
}
Tester dog = new Tester(true, new Dog());
Tester cat = new Tester(false, new Cat());
Tester monkey = new Tester(false, new Monkey());
Tester[] tests = Arrays.asList(dog, cat, monkey);
for (Tester t: tests) {
boolean actual = t.canDance();
assertTrue(actual == t.expected);
}
}
参数化您的测试似乎仍然是此类用例的教科书解决方案。 JUnit Jupiter's syntax 确实让它更优雅了一点,不过。 API 更清楚,恕我直言(测试有参数,注释显示它们的来源):
public class ListTest {
public static Stream<List<String>> lists() {
return Stream.of(new ArrayList<>(), new LinkedList<>());
}
@ParameterizedTest
@MethodSource("lists")
public void testAdd(List<String> list) {
list.add("xyz");
assertEquals(1, list.size());
assertFalse(list.isEmpty());
assertEquals("xyz", list.get(0));
}
}
我正在寻找最易读的方式来共享接口不同实现的测试。
关于这个主题的最受欢迎但相当古老的问题是 - Writing a single unit test for multiple implementations of an interface.
针对上述问题,给出了 2 个主要和不同的答案 -
- 参数化测试。
- 测试继承。
我对这两个答案都不满意。
参数化测试 - 答案不包括如何对每个子类进行参数化的代码示例。另外,我个人很难进行参数化测试,我发现 API 一点也不直观。
我总是害怕过度使用继承,而且我不确定测试继承是否是一个好的做法。
想知道2018年这个问题的最佳答案是什么
可能不是最像 Java 的,但您可以遵循 table 驱动的测试格式。使用本地 class,以保持测试的可读性,并使上下文尽可能接近真实测试。
注意:这与 @RunWith(Parameterized.class)
// Assuming Animal interface has a `public boolean canDance()`
@Test
public void TestAnimalCanDance() {
class Tester {
String errMsgFmt = "%s failed the test";
boolean expected;
Animal animal;
public Tester(boolean expected, Animal animal) {
this.expected = expected;
this.animal = animal;
}
}
Tester dog = new Tester(true, new Dog());
Tester cat = new Tester(false, new Cat());
Tester monkey = new Tester(false, new Monkey());
Tester[] tests = Arrays.asList(dog, cat, monkey);
for (Tester t: tests) {
boolean actual = t.canDance();
assertTrue(actual == t.expected);
}
}
参数化您的测试似乎仍然是此类用例的教科书解决方案。 JUnit Jupiter's syntax 确实让它更优雅了一点,不过。 API 更清楚,恕我直言(测试有参数,注释显示它们的来源):
public class ListTest {
public static Stream<List<String>> lists() {
return Stream.of(new ArrayList<>(), new LinkedList<>());
}
@ParameterizedTest
@MethodSource("lists")
public void testAdd(List<String> list) {
list.add("xyz");
assertEquals(1, list.size());
assertFalse(list.isEmpty());
assertEquals("xyz", list.get(0));
}
}