【问题标题】:Junit5 test multiple implementations of the same interfaceJunit5测试同一个接口的多个实现
【发布时间】:2020-05-21 15:09:17
【问题描述】:

我在 IAdder.java 中有以下代码:

public interface IAdder {

int add(int a, int b);

}

然后是以下实现(一个在 SimpleAdder.java 中,另一个在 AbsAdder.java 中):

public class SimpleAdder implements IAdder {

@Override
public int add(int a, int b) {
    return a+b;
}

}

public class AbsAdder implements IAdder {

@Override
public int add(int a, int b) {
    return Math.abs(a) + Math.abs(b);
}

}

现在我想用 Junit5 进行测试,所以我开始在 SimpleAddertest.java 中编写以下内容:

import org.junit.jupiter.api.Test;

导入静态 org.junit.jupiter.api.Assertions.*;

类 SimpleAdderTest {

IAdder ia = new SimpleAdder();

@Test
void add() {
    assertEquals(10, ia.add(7, 3));
}

}

为了测试 AbsAdder,我可以添加以下测试类 AbsAdderTest:

import org.junit.jupiter.api.Test;

导入静态 org.junit.jupiter.api.Assertions.*;

类 AbsAdderTest {

IAdder ia = new AbsAdder();

@Test
void add() {
    assertEquals(10, ia.add(7, 3));
}

}

在 Junit5 中避免这种代码重复的最佳方法是什么?我在 SO 上看过其他帖子,但没有人以简单的方式回答这个简单的问题。

【问题讨论】:

  • 什么代码重复?它们是两种不同的实现,因此您需要测试这两个用例。同样,您需要在两者中测试add(-5,-7),但结果不同。
  • 我认为这不能称为代码重复,因为您正在测试不同的实现。将来可能会有另一种实现,不会给出 7+3=10。

标签: java junit5


【解决方案1】:

您可以使用@ParameterizedTest,在那里您可以通过实施和测试用例,例如

@ParameterizedTest
@MethodSource("sourceMethod")
public void test(IAdder add, int a, int b, int expected) {
    assertEquals(expected, add.add(a, b));
}

public static Stream<Arguments> sourceMethod() {
    final SimpleAdder simpleAdder = new SimpleAdder();
    final AbsAdder absAdder = new AbsAdder();
    return Stream.of(
            Arguments.of(simpleAdder, 2, 3, 5),
            // add more test cases for SimpleAdder, e.g. 
            Arguments.of(simpleAdder, 2, 0, 2),
            Arguments.of(simpleAdder, 0, 4, 4),
            Arguments.of(absAdder, -2, -5, 7),
            // add more test cases for AbsAdder, e.g. 
            Arguments.of(absAdder, -2, 0, 2),
            Arguments.of(absAdder, 0, -9, 9)
    );
}

【讨论】:

  • 不要认为 assertThat(add.add(a, b), equalTo(expected));是 Junit5 的一部分吗?
  • 需要将该行更改为 assertEquals(expected, add.add(a, b));
  • 如果我想将 MethodSource 添加到类中的所有测试中怎么办?
  • @FrancescoDassisis 是的,很抱歉,我使用的是 hamcrest,感谢您的编辑! import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.junit.MatcherAssert.*;
  • 您可以拥有任意数量的 MethodSource 和任意数量的 ParameterizedTest。所有 JUnit 关心的是有一个静态方法,它返回一个参数流和与参数化测试的签名匹配的参数的数量/类型。这是你问的吗?可能我没听懂你的最后一个问题?
猜你喜欢
  • 1970-01-01
  • 2015-07-28
  • 2011-01-28
  • 2014-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-24
  • 2020-12-25
相关资源
最近更新 更多