Lista de objetos Java a Pepino DataTable para realizar diff

votos
3

Tengamos el siguiente archivo de función,

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         | 

Imagínese, después del paso llama a un extremo REST que devuelve un JSON.

Cuando buscado departamento = 'HR'

Aquí está el reposo JSON,

[
  {
    id: 1,
    name: Jack,
    department: HR
  },
  {
    id: 3,
    name: Mike,
    department: HR
  }
]

Correspondiente clase Java,

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Employee {

  private Integer id;
  private String name;
  private String department;

}

En la versión más antigua del pepino (es decir, 1.2.4), podemos hacer DataTable.diff (List <Map <String, String> real) como abajo,

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

Actualmente, nos pasaron a siguiente versión de pepino,

<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

PROBLEMA: En pepino 1.2.4 versiones, DataTable puede diff'ed con una lista <Map <String, String>. En la versión más reciente (4.0.0), DataTable.diff espera un DataTable como argumento y no existe un método para apoyar Lista diff'ing.

Ahora, tenemos que crear un objeto de tabla de datos de la lista <Map <String, String>. por lo que podemos hacer expectedDataTable.diff (actualDataTable).

PREGUNTA: ¿Hay una manera fácil de convertir Matriz de objetos JSON o List <JavaObject> a un DataTable para que podamos hacer diff de 2 tablas de datos sin crear lista <Lista <String >> de la lista de objetos que requiere una gran cantidad de código.

Publicado el 27/11/2018 a las 16:52
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
4

La revelación completa: Escribí el módulo de la tabla de datos de pepino.

Mapear manualmente objetos desde y hacia las tablas de datos es mucho tiempo, aburrido y propenso a errores. Esto es mejor dejar a un mapeador objeto. Además, la aplicación utiliza para comparar una mesa de List<Map<String, String>>magia contenidos, lanzallamas y trampas. Así que pensé que lo mejor es que se lo saltan.

solución 1

Lo primero que quiero hacer es actualizar a v4.2.0 .

A continuación, poner la siguiente configuración en algún lugar de la ruta de pegamento. El asignador de objeto es de Jackson. Por lo general, viene con la primavera.

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

Luego vuelva a colocar @Gettery @Settercon @Datalo que hashcode, equalsy toStringestán todos en marcha.

@Data
public class Employee {

  private Integer id;
  private String name;
  private String department;

}

A continuación, modifique su paso para utilizar una lista de empleados en lugar de una tabla de datos. El mapeador objeto instalado en el paso anterior se encargará de la transformada de la tabla de datos de objetos.

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

Para realizar la orden comparación insensible a considerar el uso de AssertJs assertThaten lugar de JUnits assertEquals- por lo general viene con la primavera

solución 2

Añadir datatable-matchersa sus dependencias

<groupId>io.cucumber</groupId>
<artifactId>datatable-matchers</artifactId>

Crear su propia tabla de datos y compararlo con el DataTableHasTheSameRowsAsde coincidencias.

@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);
}
Respondida el 01/12/2018 a las 11:16
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more