我正在编写一个名为Fibonacci的类,其中包含三个静态方法,这些方法使用不同的方法(递归,记忆等)实现了Fibonacci系列的三种不同实现。
然后,我创建了一个测试包,并在其中创建了一个简单的junit测试,该测试检查将负数传递给fibonacci函数时是否引发异常:
@Test
void testIllegalArgumentException() {
Assertions.assertThrows(IllegalArgumentException.class,
() -> Fibonacci.fibonacci_recursive(-2));
}
我的问题是:是否可以编写一个将函数作为参数的测试?换句话说,我要避免编写以下内容:
@Test
void testIllegalArgumentException() {
Assertions.assertThrows(IllegalArgumentException.class,
() -> Fibonacci.fibonacci_recursive(-2));
}
@Test
void testIllegalArgumentException() {
Assertions.assertThrows(IllegalArgumentException.class,
() -> Fibonacci.fibonacci_second(-2));
}
@Test
void testIllegalArgumentException() {
Assertions.assertThrows(IllegalArgumentException.class,
() -> Fibonacci.fibonacci_third(-2));
}
答案 0 :(得分:4)
Java 8 + Junit5允许您创建@ParameterizedTest
。作为参数列表,您可以传递要测试的功能。以下测试将使用不同的输入功能运行3次。
测试样本:
@ParameterizedTest
@MethodSource("getSource")
void whenNegativeValue_thenThrowException(Function<Integer, Integer> function, Integer value) {
Assertions.assertThrows(IllegalArgumentException.class,
() -> function.apply(value));
}
private static Stream<Arguments> getSource() {
Function<Integer, Integer> first = Fib::first;
Function<Integer, Integer> second = Fib::second;
Function<Integer, Integer> third = Fib::third;
return Stream.of(
Arguments.of(first, -1),
Arguments.of(second, -2),
Arguments.of(third, -3)
);
}
类实现:
public class Fib {
public static int first(int i) {
System.out.println("first");
validate(i);
return i;
}
public static int second(int i) {
System.out.println("second");
validate(i);
return i;
}
public static int third(int i) {
System.out.println("third");
validate(i);
return i;
}
private static void validate(int i) {
if (i < 0) {
throw new IllegalArgumentException();
}
}
}
答案 1 :(得分:1)
一种基本方法是将通用代码移到一个接受要调用的功能的助手中,并简单地从测试中调用它。
// Helper
public void testFibo(Supplier<Integer> supplier) {
Assertions.assertThrows(IllegalArgumentException.class,
supplier.get());
}
// Usage inside test
testFibo(() -> Fibonacci.fibonacci_recursive(-2));
也就是说,测试框架可以提供更优雅的方法。我只是不确定junit是其中之一。