gpt4 book ai didi

java - Java 对象列表到 Cucumber DataTable 以执行差异

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:00:56 27 4
gpt4 key购买 nike

让我们拥有以下特征文件,

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 |

想象一下,接下来的步骤调用一个返回 JSON 的 REST 端点。

When searched for department = 'HR'

这是 repose 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;

}

在旧版本的 cucumber(即 1.2.4)中,我们可以像下面那样做 DataTable.diff(List actual),

@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);
}

目前我们升级到以下 cucumber 版本,

<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

PROBLEM: In cucumber 1.2.4 versions, DataTable can be diff'ed with a List<Map<String, String>. In the newer version (4.0.0), DataTable.diff expects a DataTable as argument and there is no method to support diff'ing List.

Now, we need to create a datatable object from List<Map<String, String>. so that we can do expectedDataTable.diff(actualDataTable).

QUESTION: Is there a easy way to convert Array of JSON Object or List<JavaObject> to a DataTable so that we can do diff of 2 datatables without creating List<List<String>> from list of objects which requires a lot of code.

最佳答案

全面披露:我为 Cucumber 编写了数据表模块。

手动将对象从数据表映射到数据表非常耗时、乏味且容易出错。这最好留给对象映射器。此外,用于将表与 List<Map<String, String>> 进行比较的实现包含魔法、火焰喷射器和陷阱。所以我认为最好将其排除在外。

解决方案一

你要做的第一件事是upgrade to v4.2.0 .

然后将以下配置放在粘合路径的某处。对象映射器来自 Jackson。它通常与 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 , equalstoString都实现了。

@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 一起提供

方案二

添加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);
}

关于java - Java 对象列表到 Cucumber DataTable 以执行差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53504489/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com