私たちは、次の機能ファイルを持ってみましょう、
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エンドポイント以下、想像してみてください。
部門=「HR」の検索とき
ここで安息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(実際一覧<地図<文字列、文字列>)行うことができ、
@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 <地図<文字列、文字列>でdiff'edすることができます。新しいバージョン(4.0.0)では、DataTable.diffは、引数としてのDataTableを期待してdiff'ingリストをサポートする方法はありません。
今、私たちは、List <地図<文字列、文字列>からDataTableオブジェクトを作成する必要があります。私たちはexpectedDataTable.diff(actualDataTable)を行うことができます。
QUESTION: JSONオブジェクトまたはList <JavaObjectオブジェクト>の変換アレイへの簡単な方法は、我々は多くのコードを必要とするオブジェクトのリストからリスト<リスト<文字列を>>作成せずに2つのDataTableのdiffを行うことができるようにデータテーブルにあります。
完全な情報開示:私はキュウリのためのデータ・テーブル・モジュールを書きました。
データテーブルからとを手動でマッピングオブジェクト時間が発生しやすい、かかり退屈とエラーになります。これは最高のオブジェクトマッパーに任されています。さらに、実装はにテーブルを比較するために使用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
-それは通常、春が付属しています
解決策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);
}