我正在寻找一种最易读的方式来共享接口的不同实现的测试。
关于此主题的最受欢迎但相当古老的问题是- Writing a single unit test for multiple implementations of an interface。
对于上述问题,给出了2个主要且不同的答案-
两个答案我都不满意。
参数化测试-答案不包括如何参数化每个子类的代码示例。另外,我个人很难进行参数化测试,我发现API根本不直观。
我总是担心继承会过度使用,而且我不确定测试继承是否是一种好习惯。
我想知道2018年该问题的最佳答案是什么。
答案 0 :(得分:1)
参数化测试似乎仍然是此类用例的教科书解决方案。 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));
}
}
答案 1 :(得分:0)
可能不是最类似于Java的,但是您可以遵循表驱动的测试格式。使用本地类,可以使测试保持最高可读性,并使上下文尽可能接近真实测试。
注意:这与@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);
}
}