让我们拥有以下特性文件,
Feature: Search Employees
Background:
Given following employees exists
| id | name | department |
| 1 | Jack | HR |
| 2 | Rachel | Finance |
| 3 | Mike | HR |
| 4 | Emma | IT |
Scenario: Get Employees By Department
Given user wants to get list employees in a department
When searched for department = 'HR'
Then following list of employees are returned
| id | name | department |
| 1 | Jack | HR |
| 3 | Mike | HR | 设想,下面的步骤调用一个REST端点,该端点返回JSON.
搜索部门=“人力资源”
这里是静止的JSON,
[
{
"id": 1,
"name": "Jack",
"department": "HR"
},
{
"id": 3,
"name": "Mike",
"department": "HR"
}
]对应的Java类,
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Employee {
private Integer id;
private String name;
private String department;
}在老版本的黄瓜(即1.2.4),我们可以做DataTable.diff(List实际)如下,
@Then("^following list of employees are returned$")
public void following_list_of_employees_are_returned(DataTable expectedEmployees) throws Throwable {
List<Map<String, Object>> actualEmployees = new ArrayList<>();
List<Employee> employees = response.as(Employee[].class);
employees
.forEach(e -> {
Map<String, Object> map = new HashMap<>();
map.put("id", e.getId());
map.put("name", e.getName());
map.put("department", e.getDepartment());
actualEmployees.add(map);
});
expectedEmployees.unorderedDiff(actualEmployees);
}当前,我们升级到下面的黄瓜版本,
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java8</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-spring</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
[INFO] +- io.cucumber:cucumber-java8:jar:4.0.0:test
[INFO] | +- io.cucumber:cucumber-java:jar:4.0.0:test
[INFO] | \- net.jodah:typetools:jar:0.5.0:test
[INFO] +- io.cucumber:cucumber-spring:jar:4.0.0:test
[INFO] \- io.cucumber:cucumber-junit:jar:4.0.0:test
[INFO] \- io.cucumber:cucumber-core:jar:4.0.0:test
[INFO] +- io.cucumber:cucumber-html:jar:0.2.7:test
[INFO] +- io.cucumber:gherkin:jar:5.1.0:test
[INFO] +- io.cucumber:tag-expressions:jar:1.1.1:test
[INFO] +- io.cucumber:cucumber-expressions:jar:6.1.0:test
[INFO] \- io.cucumber:datatable:jar:1.1.3:test
[INFO] \- io.cucumber:datatable-dependencies:jar:1.1.3:test问题:在黄瓜1.2.4版本中,DataTable可以用List来区别。在较新的版本(4.0.0)中,DataTable.diff需要一个DataTable作为参数,并且没有支持diff‘’ing列表的方法。 现在,我们需要从List创建datatable对象。这样我们就可以做expectedDataTable.diff(actualDataTable)了。 问题:是否有一种简单的方法可以将JSON对象或列表的数组转换为DataTable,这样我们就可以在不需要大量代码的对象列表中创建List来区分2种数据。
发布于 2018-12-01 11:16:51
完全公开:我为Cucumber编写了数据表模块。
手动将对象从数据表映射到数据表是耗时、乏味和容易出错的。这最好留给对象映射器。此外,用于将表与List<Map<String, String>>进行比较的实现包含魔术、火焰喷射器和陷阱。所以我觉得最好把它忘了。
解决方案1
您要做的第一件事是升级到v4.2.0。
然后将下面的配置放在胶水路径的某个位置。物体映射器是来自杰克逊的。它通常伴随着春天。
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匹配器进行比较。
@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);
}发布于 2021-06-29 17:01:10
很好的答案,我和你有相同的解决方案,但我遇到了一种情况:如果我们有:
public class Employee {
private Integer id;
private String name;
private List<String> department;
}我有没有办法做这样的测试:
Then following list of employees are returned
| id | name | department |
| 1 | Jack | HR, IT |
| 3 | Mike | HR | 意思是怎么告诉黄瓜我有一份部门的名单?
顺便说一句,对于您的具体情况,因为您没有使用List或Hashset,所以您只需使用:
@DefaultParameterTransformer
@DefaultDataTableEntryTransformer(replaceWithEmptyString = "[blank]")
@DefaultDataTableCellTransformer
public Object transformer(Object fromValue, Type toValueType) {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.convertValue(fromValue, objectMapper.constructType(toValueType));
}并将其添加到步骤定义中,而无需创建ParameterTypes类。
https://stackoverflow.com/questions/53504489
复制相似问题