如何在 JUnitParams 参数提供程序中使用 Mockito 存根?
How to use Mockito stubs in a JUnitParams parameter provider?
我正在努力学习 JUnit。在处理特定问题时,我决定使用 JUnitParams 参数提供程序。我正在编写的测试方法的每组参数都应包含两个输入值和一个列表,用于测试方法调用的结果:
private static final Object[] getConstraints() {
return new Object[]{
new Object[]{15, Equipment.WHITEBOARD, Arrays.asList(new Classroom[]{classroomA, classroomB})},
new Object[]{15, Equipment.PROJECTOR, Arrays.asList(new Classroom[]{classroomB})},
new Object[]{15, Equipment.MICROPHONE, Arrays.asList(new Classroom[]{classroomA})},
new Object[]{30, Equipment.WHITEBOARD, Arrays.asList(new Classroom[]{classroomB})},
new Object[]{30, Equipment.PROJECTOR, Arrays.asList(new Classroom[]{classroomB})},
new Object[]{30, Equipment.MICROPHONE, Arrays.asList(new Classroom[]{})},
new Object[]{45, Equipment.WHITEBOARD, Arrays.asList(new Classroom[]{})},
new Object[]{45, Equipment.PROJECTOR, Arrays.asList(new Classroom[]{})},
new Object[]{45, Equipment.MICROPHONE, Arrays.asList(new Classroom[]{})},
};
}
classroomA
和 classroomB
实际上是每次测试执行前准备的 Mockito 存根:
@Before
public void setUp() {
classroomA = mock(Classroom.class);
classroomB = mock(Classroom.class);
classrooms = Arrays.asList(new Classroom[]{classroomA, classroomB});
when(classroomA.getName()).thenReturn("A");
when(classroomA.getCapacity()).thenReturn(20);
when(classroomA.getEquipment()).thenReturn(Arrays.asList(new Equipment[]{Equipment.WHITEBOARD, Equipment.MICROPHONE}));
when(classroomB.getName()).thenReturn("B");
when(classroomB.getCapacity()).thenReturn(40);
when(classroomB.getEquipment()).thenReturn(Arrays.asList(new Equipment[]{Equipment.WHITEBOARD, Equipment.PROJECTOR}));
bookingSystem = new BookingSystem(classrooms);
}
当我尝试使用上述 Classroom
个对象列表时出现问题:
@Test
@Parameters(method = "getConstraints")
public void shouldBookClassroomMeetingConstraints(int capacity, Equipment equipment, List<Classroom>
suitableClassrooms) {
Assert.assertTrue("Should book a classroom that has a minimum capacity of " + capacity + " and has " +
equipment,
suitableClassrooms.contains(bookingSystem.book(capacity, equipment, ANY_DAY_OF_WEEK, ANY_HOUR)));
}
调试显示第一个 运行 suitableClassrooms
包含 2 个对象,但进一步检查显示所有元素均为空 - 我准备的存根不存在。显然,测试没有在应该通过或失败的地方通过或失败。
将 JUnitParams 与 Mockito 一起使用是否有限制,还是我使用错误?正确的使用方法是什么?
也有可能这是单元测试的错误技术。如果是这种情况,编写验证方法调用的结果是否在给定数组中的测试的正确方法是什么?
您需要让 class 知道您是 运行 Mockito 的测试用例。在下面的 class 级别添加它应该可以工作。
@RunWith(MockitoJUnitRunner.class)
您的测试不起作用,因为 JUnitParamsRunner
运行程序在调用 @Before
方法之前甚至在 @BeforeClass
之前收集测试参数(即调用 getConstraints
方法)。所以 classroomA
和 classroomB
在那一刻是空的。这就是 suitableClassrooms
由空元素组成的原因。
解决方法是在getConstraints()
方法中初始化classroomA
和classroomB
。
此外,我相信您可以在这里摆脱 mockito。 Classroom
看起来像 POJO,没有必要模拟 POJO。在这种情况下,您只需要创建 Classroom
实例并用必要的数据填充它。
我正在努力学习 JUnit。在处理特定问题时,我决定使用 JUnitParams 参数提供程序。我正在编写的测试方法的每组参数都应包含两个输入值和一个列表,用于测试方法调用的结果:
private static final Object[] getConstraints() {
return new Object[]{
new Object[]{15, Equipment.WHITEBOARD, Arrays.asList(new Classroom[]{classroomA, classroomB})},
new Object[]{15, Equipment.PROJECTOR, Arrays.asList(new Classroom[]{classroomB})},
new Object[]{15, Equipment.MICROPHONE, Arrays.asList(new Classroom[]{classroomA})},
new Object[]{30, Equipment.WHITEBOARD, Arrays.asList(new Classroom[]{classroomB})},
new Object[]{30, Equipment.PROJECTOR, Arrays.asList(new Classroom[]{classroomB})},
new Object[]{30, Equipment.MICROPHONE, Arrays.asList(new Classroom[]{})},
new Object[]{45, Equipment.WHITEBOARD, Arrays.asList(new Classroom[]{})},
new Object[]{45, Equipment.PROJECTOR, Arrays.asList(new Classroom[]{})},
new Object[]{45, Equipment.MICROPHONE, Arrays.asList(new Classroom[]{})},
};
}
classroomA
和 classroomB
实际上是每次测试执行前准备的 Mockito 存根:
@Before
public void setUp() {
classroomA = mock(Classroom.class);
classroomB = mock(Classroom.class);
classrooms = Arrays.asList(new Classroom[]{classroomA, classroomB});
when(classroomA.getName()).thenReturn("A");
when(classroomA.getCapacity()).thenReturn(20);
when(classroomA.getEquipment()).thenReturn(Arrays.asList(new Equipment[]{Equipment.WHITEBOARD, Equipment.MICROPHONE}));
when(classroomB.getName()).thenReturn("B");
when(classroomB.getCapacity()).thenReturn(40);
when(classroomB.getEquipment()).thenReturn(Arrays.asList(new Equipment[]{Equipment.WHITEBOARD, Equipment.PROJECTOR}));
bookingSystem = new BookingSystem(classrooms);
}
当我尝试使用上述 Classroom
个对象列表时出现问题:
@Test
@Parameters(method = "getConstraints")
public void shouldBookClassroomMeetingConstraints(int capacity, Equipment equipment, List<Classroom>
suitableClassrooms) {
Assert.assertTrue("Should book a classroom that has a minimum capacity of " + capacity + " and has " +
equipment,
suitableClassrooms.contains(bookingSystem.book(capacity, equipment, ANY_DAY_OF_WEEK, ANY_HOUR)));
}
调试显示第一个 运行 suitableClassrooms
包含 2 个对象,但进一步检查显示所有元素均为空 - 我准备的存根不存在。显然,测试没有在应该通过或失败的地方通过或失败。
将 JUnitParams 与 Mockito 一起使用是否有限制,还是我使用错误?正确的使用方法是什么?
也有可能这是单元测试的错误技术。如果是这种情况,编写验证方法调用的结果是否在给定数组中的测试的正确方法是什么?
您需要让 class 知道您是 运行 Mockito 的测试用例。在下面的 class 级别添加它应该可以工作。
@RunWith(MockitoJUnitRunner.class)
您的测试不起作用,因为 JUnitParamsRunner
运行程序在调用 @Before
方法之前甚至在 @BeforeClass
之前收集测试参数(即调用 getConstraints
方法)。所以 classroomA
和 classroomB
在那一刻是空的。这就是 suitableClassrooms
由空元素组成的原因。
解决方法是在getConstraints()
方法中初始化classroomA
和classroomB
。
此外,我相信您可以在这里摆脱 mockito。 Classroom
看起来像 POJO,没有必要模拟 POJO。在这种情况下,您只需要创建 Classroom
实例并用必要的数据填充它。