Java 有没有办法在单个@test中测试一组输入和一组输出?
有没有办法进行一系列类似的测试,比如Java 有没有办法在单个@test中测试一组输入和一组输出?,java,unit-testing,mockito,Java,Unit Testing,Mockito,有没有办法进行一系列类似的测试,比如 @Test public void testA() { when(foo.getVal()).thenReturn("A"); response = myService.doThings(foo); assert(response.getCode() == 200); } @Test public void testB() { when(foo.getVal()).thenReturn("B");
@Test
public void testA() {
when(foo.getVal()).thenReturn("A");
response = myService.doThings(foo);
assert(response.getCode() == 200);
}
@Test
public void testB() {
when(foo.getVal()).thenReturn("B");
response = myService.doThings(foo);
assert(response.getCode() == 404);
}
@Test
public void testC() {
when(foo.getVal()).thenReturn("C");
response = myService.doThings(foo);
assert(response.getCode() == 200);
}
并执行类似于合成语法的操作:
@Test
public void testABC() {
when(foo.getVal()).thenReturnEach("A", "B", "C");
response = myService.doThings(foo);
assertEach(/* somehow check a list of 200, 404, 200 */);
}
您需要的是一个参数化测试。 其思想是定义一个通用方法,在该方法中定义一组输入和一组预期输入 但是Mockito在这里没有帮助,因为运行/执行测试不是模拟库的工作。 我最喜欢的单元测试库是JUnit,它将很好地解决这个问题 例如,使用old way,您可以编写如下内容:
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class MyServiceTest {
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{ "A", 200 }, { "B", 404 }, { "C", 200 }
});
}
private int valInput;
private String responseCodeOutput;
private Foo foo = ...;
public MyServiceTest(String valInput, int responseCodeOutput) {
this.valInput = valInput;
this.responseCodeOutput = responseCodeOutput;
}
@Test
public void doThings() {
when(foo.getVal()).thenReturnEach(valInput);
String response = myService.doThings(foo);
Assert.assertEqual(responseCodeOutput, response);
}
}
对于最近发布的JUnit 5,它将更加干净和简单:
@ParameterizedTest
@MethodSource("doThingsProvider")
void doThings (String valInput, int expectedCode) {
when(foo.getVal()).thenReturnEach(valInput);
String response = myService.doThings(foo);
Assert.assertEqual(expectedCode, response);
}
static Stream<Arguments> doThingsProvider() {
return Stream.of(
Arguments.of("A", 200),
Arguments.of("B", 404),
Arguments.of("C", 200),
);
}
您需要的是一个参数化测试。 其思想是定义一个通用方法,在该方法中定义一组输入和一组预期输入 但是Mockito在这里没有帮助,因为运行/执行测试不是模拟库的工作。 我最喜欢的单元测试库是JUnit,它将很好地解决这个问题 例如,使用old way,您可以编写如下内容:
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class MyServiceTest {
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{ "A", 200 }, { "B", 404 }, { "C", 200 }
});
}
private int valInput;
private String responseCodeOutput;
private Foo foo = ...;
public MyServiceTest(String valInput, int responseCodeOutput) {
this.valInput = valInput;
this.responseCodeOutput = responseCodeOutput;
}
@Test
public void doThings() {
when(foo.getVal()).thenReturnEach(valInput);
String response = myService.doThings(foo);
Assert.assertEqual(responseCodeOutput, response);
}
}
对于最近发布的JUnit 5,它将更加干净和简单:
@ParameterizedTest
@MethodSource("doThingsProvider")
void doThings (String valInput, int expectedCode) {
when(foo.getVal()).thenReturnEach(valInput);
String response = myService.doThings(foo);
Assert.assertEqual(expectedCode, response);
}
static Stream<Arguments> doThingsProvider() {
return Stream.of(
Arguments.of("A", 200),
Arguments.of("B", 404),
Arguments.of("C", 200),
);
}
需要参数化测试,但在OP示例中,也需要类似Mockito的模拟库,因为参数化的是协作者的行为,而不是SUT的输入。@Kevin Welker我完全同意。我提到了测试执行。我更新为更具体一点。在两个示例中,我认为您都有参数类型reversed@Kevin韦尔克:你说得对。在没有IDE的情况下编写代码有时有点容易出错。我纠正了。感谢您:需要参数化测试,但在OP示例中,也需要像Mockito这样的模拟库,因为参数化的是协作者的行为,而不是SUT的输入。@Kevin Welker我完全同意。我提到了测试执行。我更新为更具体一点。在两个示例中,我认为您都有参数类型reversed@Kevin韦尔克:你说得对。在没有IDE的情况下编写代码有时有点容易出错。我纠正了。多谢各位: