Полное раскрытие: я написал модуль таблицы данных для Cucumber.
Ручное отображение объектов из и в таблицы данных занимает много времени, скучно и подвержено ошибкам.Это лучше оставить объектному картографу.Кроме того, реализация, используемая для сравнения таблицы с List<Map<String, String>>
, содержала магию, огнеметы и ловушки.Поэтому я подумал, что лучше не указывать.
Решение 1
Первое, что вы хотите сделать, это обновить до v4.2.0 .
Затем поместите следующую конфигурацию где-нибудь на пути клея.Картограф объекта от Джексона.Обычно он поставляется с Spring.
public class ParameterTypes implements TypeRegistryConfigurer {
@Override
public Locale locale() {
return ENGLISH;
}
@Override
public void configureTypeRegistry(TypeRegistry typeRegistry) {
Transformer transformer = new Transformer();
typeRegistry.setDefaultDataTableCellTransformer(transformer);
typeRegistry.setDefaultDataTableEntryTransformer(transformer);
typeRegistry.setDefaultParameterTransformer(transformer);
}
private class Transformer implements ParameterByTypeTransformer, TableEntryByTypeTransformer, TableCellByTypeTransformer {
ObjectMapper objectMapper = new ObjectMapper();
@Override
public Object transform(String s, Type type) {
return objectMapper.convertValue(s, objectMapper.constructType(type));
}
@Override
public <T> T transform(Map<String, String> map, Class<T> aClass, TableCellByTypeTransformer tableCellByTypeTransformer) {
return objectMapper.convertValue(map, aClass);
}
@Override
public <T> T transform(String s, Class<T> aClass) {
return objectMapper.convertValue(s, aClass);
}
}
}
Затем замените @Getter
и @Setter
на @Data
, так что hashcode
, equals
и toString
все реализованы.
@Data
public class Employee {
private Integer id;
private String name;
private String department;
}
Затем измените ваш шаг, чтобы использовать список сотрудников вместо таблицы данных.Установщик объектов, установленный на предыдущем шаге, будет обрабатывать преобразование из таблицы данных в объекты.
@Then("^following list of employees are returned$")
public void following_list_of_employees_are_returned(List<Employee> expectedEmployees) throws Throwable {
List<Map<String, Object>> actualEmployees = new ArrayList<>();
List<Employee> employees = response.as(Employee[].class);
assertEquals(expectedEmployees, actualEmployees);
}
Чтобы сделать порядок сравнения нечувствительным, рассмотрите использование AssertJs assertThat
вместо JUnits assertEquals
- обычно оно поставляется сSpring
Решение 2
Добавьте datatable-matchers
к вашим зависимостям
<groupId>io.cucumber</groupId>
<artifactId>datatable-matchers</artifactId>
Создайте свою собственную таблицу данных и сравните ее, используя DataTableHasTheSameRowsAs
matcher.
@Then("^following list of employees are returned$")
public void following_list_of_employees_are_returned(DataTable expectedEmployees) {
List<Employee> employees = response.as(Employee[].class);
DataTable actualEmployees = createTable(
employees,
asList("id", "name", "department"),
Employee::getId, Employee::getName, Employee::getDepartment
);
assertThat(actualEmployees, hasTheSameRowsAs(expectedEmployees));
}
static <T> DataTable createTable(List<T> values, List<String> headers, Function<T, Object>... extractors) {
List<List<String>> rawTable = new ArrayList<>();
rawTable.add(headers);
values.stream()
.map(employee -> Stream.of(extractors)
.map(f -> f.apply(employee))
.map(String::valueOf)
.collect(Collectors.toList()))
.forEach(rawTable::add);
return create(rawTable);
}