如何在模拟 returns 无序集合映射时测试 API 行为?
How do I test the API behavior when mock returns unordered collection Map?
我有一个 API,API 调用一个服务,该服务 returns Map<String, List<String>>
,API 将其转换为列表并 returns 它.
public List<EmployeeWrapper> getEmployees(int id) {
Map<Integer, List<String>> employees = employeeRepository.getEmployees(id);
return employees.entrySet().stream()
.map(entry -> new EmployeeWrapper(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
}
现在,我需要编写一个测试用例来涵盖此行为,但这里的问题是 Mock
returns HashMap
并且 List<EmployeeWrapper>
的顺序可能是每次调用都不同。
@Test
void testEmployeeService() {
// when
EmployeeRepository employeeRepository = Mockito.mock(EmployeeRepository.class);
Map<Integer, List<String>> employeeIdsToEmployee =
Map.of(1, List.of("HR", "Account"), 2, List.of("Marketing"));
Mockito.when(employeeRepository.getEmployees(Mockito.any())).thenReturn(employeeIdsToEmployee);
// call service
List<EmployeeWrapper> employees = employeeService.getEmployees(10);
// assert
assertThat(employees).isNotNull().hasSize(2);
EmployeeWrapper employeeWrapper1 = employees.get(0);
EmployeeWrapper employeeWrapper2 = employees.get(1);
assertThat(employeeWrapper1).isNotNull().extracting("id", "departments")
.containsExactly(1, List.of("HR", "Account"));
assertThat(employeeWrapper2).isNotNull().extracting("id", "departments")
.containsExactly(2, List.of("Marketing"));
}
这里的问题是 employees.get(0)
并且 employees.get(1)
不会总是同一个对象,因为员工列表是使用无序集合构建的。
是否有更好的方法来测试 API 的行为是否依赖于无序集合?
AssertJ 的可迭代断言有一个 'containsExactlyInAnyOrder' 方法。
您必须在列表中开始断言:
assertThat(employees)
.extracting("id", "departments")
.containsExactlyInAnyOrder(
tuple(1, List.of("HR", "Account")),
tuple(2, List.of("Marketing")));
顺便说一句,提取方法也支持lambda,所以可以是:
assertThat(employees)
.extracting(
EmployeeWrapper::getId,
EmployeeWrapper::getDepartments)
.containsExactlyInAnyOrder(
tuple(1, List.of("HR", "Account")),
tuple(2, List.of("Marketing")));
我有一个 API,API 调用一个服务,该服务 returns Map<String, List<String>>
,API 将其转换为列表并 returns 它.
public List<EmployeeWrapper> getEmployees(int id) {
Map<Integer, List<String>> employees = employeeRepository.getEmployees(id);
return employees.entrySet().stream()
.map(entry -> new EmployeeWrapper(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
}
现在,我需要编写一个测试用例来涵盖此行为,但这里的问题是 Mock
returns HashMap
并且 List<EmployeeWrapper>
的顺序可能是每次调用都不同。
@Test
void testEmployeeService() {
// when
EmployeeRepository employeeRepository = Mockito.mock(EmployeeRepository.class);
Map<Integer, List<String>> employeeIdsToEmployee =
Map.of(1, List.of("HR", "Account"), 2, List.of("Marketing"));
Mockito.when(employeeRepository.getEmployees(Mockito.any())).thenReturn(employeeIdsToEmployee);
// call service
List<EmployeeWrapper> employees = employeeService.getEmployees(10);
// assert
assertThat(employees).isNotNull().hasSize(2);
EmployeeWrapper employeeWrapper1 = employees.get(0);
EmployeeWrapper employeeWrapper2 = employees.get(1);
assertThat(employeeWrapper1).isNotNull().extracting("id", "departments")
.containsExactly(1, List.of("HR", "Account"));
assertThat(employeeWrapper2).isNotNull().extracting("id", "departments")
.containsExactly(2, List.of("Marketing"));
}
这里的问题是 employees.get(0)
并且 employees.get(1)
不会总是同一个对象,因为员工列表是使用无序集合构建的。
是否有更好的方法来测试 API 的行为是否依赖于无序集合?
AssertJ 的可迭代断言有一个 'containsExactlyInAnyOrder' 方法。
您必须在列表中开始断言:
assertThat(employees)
.extracting("id", "departments")
.containsExactlyInAnyOrder(
tuple(1, List.of("HR", "Account")),
tuple(2, List.of("Marketing")));
顺便说一句,提取方法也支持lambda,所以可以是:
assertThat(employees)
.extracting(
EmployeeWrapper::getId,
EmployeeWrapper::getDepartments)
.containsExactlyInAnyOrder(
tuple(1, List.of("HR", "Account")),
tuple(2, List.of("Marketing")));