运行 具有从同一接口派生的多个对象的同一 Junit 测试

Run same Junit Test with multiple objects derived from same interface

我正在努力提高我的测试知识 我正在尝试 运行使用从同一接口派生的不同对象实现相同的 JUnit 测试 class。

所以我们可以假设如下:

interface Base {
    void sort();
}

class  A implements Base {
    @Override
    public void sort() {
        //sort naively
    }
}

class  B implements Base {
    @Override
    public void sort() {
        //sort using another better approach
    }
}

class  C implements Base {
    @Override
    public void sort() {
        //sort using optimized approach
    }
}
class Test {
    @Test
    void test1() {

        Base obj = new A();
        obj.sort();
        obj.otherStuff();
    }
}
class SecondTest {
//trying to avoid making multiple test classes that has only one line in difference
@Test
void test1() {
    var obj = new B();
    obj.sort();
    obj.otherStuff();
}

所以我的问题是如何 运行 使用 A、B、C 中的对象进行测试 class 而不会落入重复代码和冗余的陷阱?

请注意,我写这个例子只是为了说明我的观点,sort() doStuff() 方法只是占位符,但是当你在每个测试中有超过 ~70 行代码重复时 class 它开始变得丑陋和多余。

*我看过@beforeEach、@Before、@After,但我认为我看不到这些可能对我有帮助的方法。

修复它的方法如下,您在测试 class 中创建一个方法,该方法将 Base obj 作为输入并包含所有重复行。然后你要做的是在不同的测试中初始化 obj,然后将它传递给方法。 这是一个可以完成这项工作的代码:

class Test {
@Test
void test1() {

    Base obj = new A();
    wrapperMethod(obj);
}
@Test
void test2() {
   var obj = new B();
   wrapperMethod(obj);
 }

public static void wrapperMethod(Base obj){
obj.sort();
obj.otherStuff();
}
}

根据经验,测试可以很像普通编程,其中通过保证可重用性的方法避免冗余。

干杯,

D

你可以写一个parameterized test with a MethodSource.

@ParameterizedTest
@MethodSource("bases")
@Test
void test1(Base obj) {
  obj.sort();
  obj.otherStuff();
}

static Stream<String> bases() {
  return Stream.of(new A(), new B(), new C());
}

首先,您必须确定您对 UnitTesting 的理解。

单元测试与代码(覆盖率)无关

UnitTesing 是关于验证 期望的 public 行为 其中“public 行为意味着 return 值 and/or 与依赖项的通信。 每个测试方法都应验证测试单元所需行为的单个原子假设

从这个角度来看,通过相同的测试方法传递一组共享相同接口的对象是没有意义的,因为存在这些不同的接口实现来实现接口方法,它们具有自己的独特性 行为。反过来假设对象的行为方式是唯一不同的。

如果预期所有对象的行为相同(这是单个测试方法可以验证的唯一假设),那么首先没有不同的对象(即实现)。