cucumber-jvm version 3 заменяет шаблон проектирования для простой таблицы на картуоперация - PullRequest
0 голосов
/ 07 сентября 2018

Я изучал новую поддержку io.cucumber.datatable.DataTable , представленную в cucumber-jvm: 3.0.0. У меня установлен cucumber-jvm: 3.0.2.

В моем существующем проекте cucumber-jvm: 2.4.0 используется простой шаблон проектирования, в котором я передаю таблицу в шаг, последний параметр которого имеет тип Map. Это поведение больше не поддерживается в версии 3.

Итак, я создал контрольный пример для моделирования альтернативы этому шаблону проектирования. Это работает, но возвращаемая карта не изменяется. Я работал над этим, но два вопроса:

  1. Почему возвращаемая карта неизменна? Я пропускаю важный принцип дизайна?
  2. Есть ли более простой способ достичь моей основной цели - найти шаблон замены?

Вот код:

# h/t to https://github.com/cucumber/datatable-java/edit/master/datatable/src/test/java/io/cucumber/datatable/DataTableTypeRegistryTableConverterTest.java
Feature: Test simple DataTable converters  

  @simple_no_header_map_string_string
  Scenario: Convert a two column table to a Map
    Given a basic street address
      | streetAddress | 333 W Camden St |
      | cityName      | Baltimore       |
      | stateName     | MD              |
      | postalCode    | 21201           |
    When I specify Country "US"
    Then I can print the complete address 


package some.org.stuff.cucumberjvm302testbed;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;

import io.cucumber.datatable.DataTable;
import io.cucumber.datatable.DataTable.TableConverter;
import io.cucumber.datatable.DataTableTypeRegistry;
import io.cucumber.datatable.DataTableTypeRegistryTableConverter;
import io.cucumber.datatable.TypeReference;

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

public class Cucumber302TestBedSteps {

    private Map<String,String> addressMap;

    private final DataTableTypeRegistry registry = new DataTableTypeRegistry(Locale.ENGLISH);
    private final TableConverter converter = new DataTableTypeRegistryTableConverter(registry);
    private static final Type MAP_OF_STRING_TO_STRING = new TypeReference<Map<String, String>>() {
    }.getType();

    @Given("^a basic street address$")
    public void aBasicStreetAddress(DataTable datatable) {
        //Here is the workaround to make addressMap mutable
        addressMap = new HashMap<String,String>(converter.convert(datatable, MAP_OF_STRING_TO_STRING)); 
    }

    @When("^I specify Country \"(.+)\"$")
    public void iSpecifyCountry(String inputCountry) {
        addressMap.put("country", inputCountry);
    }

    @Then("^I can print the complete address$")
    public void iCanPrintTheCompleteAddress() {
        System.out.println("\n\t" + addressMap.get("streetAddress"));
        System.out.println("\t" + addressMap.get("cityName"));
        System.out.println("\t" + addressMap.get("stateName"));
        System.out.println("\t" + addressMap.get("postalCode"));
        System.out.println("\t" + addressMap.get("country") + "\n");
    }
}

Я посмотрел на Cucumber-JVM 3 - Преобразовать DataTable в один объект, используя asMap () . Я реализовал это решение, но у меня есть несколько младших тестеров, поэтому я искал что-то более простое.

1 Ответ

0 голосов
/ 08 сентября 2018

Вам может понравиться этот шаблон:

private final Map<String,String> addressMap = new HashMap<>();

@Given("^a basic street address$")
public void aBasicStreetAddress(Map<String,String> address) {
    addressMap.putAll(address);
}

@When("^I specify Country \"(.+)\"$")
public void iSpecifyCountry(String inputCountry) {
    addressMap.put("country", inputCountry);
}

@Then("^I can print the complete address$")
public void iCanPrintTheCompleteAddress() {
    System.out.println("\n\t" + addressMap.get("streetAddress"));
    System.out.println("\t" + addressMap.get("cityName"));
    System.out.println("\t" + addressMap.get("stateName"));
    System.out.println("\t" + addressMap.get("postalCode"));
    System.out.println("\t" + addressMap.get("country") + "\n");
}

Вместо установки addressMap на данном шаге мы сначала определяем его как пустую карту. Это гарантирует, что всегда присутствует разумный подарок по умолчанию. Это делает шаги более гибкими, поскольку теперь их можно использовать в любом порядке и несколько раз. По общему признанию, имеет небольшую ценность в этом конкретном сценарии, но в целом довольно полезно

Затем на данном шаге мы устанавливаем последний параметр на Map<String,String> address. Огурец превратит DataTable в карту. Мы используем .putAll для копирования всех полей из address в addressMap.

address является неизменным, чтобы предотвратить изменение исходного ввода методами с побочными эффектами. Это полезный механизм, когда исходные данные используются позже для создания утверждений. Если объект не был явно скопирован, вы можете положиться на тот факт, что он не был изменен. Это облегчает чтение кода.

В моем существующем проекте cucumber-jvm: 2.4.0 используется простой шаблон проектирования, в котором я передаю таблицу в шаг, последний параметр которого имеет тип Map. Это поведение больше не поддерживается в версии 3.

Это поведение все еще поддерживается. Что заставило вас думать, что это не так?

закрытый окончательный реестр DataTableTypeRegistry = новый DataTableTypeRegistry (Locale.ENGLISH); закрытый финальный конвертер TableConverter = new DataTableTypeRegistryTableConverter (реестр); приватный статический финал Тип MAP_OF_STRING_TO_STRING = new TypeReference> () { } .GetType (); * * 1 023

Тебе здесь не нужно. Взгляните на TypeRegistryConfigurer . Хотя имейте в виду, что у карт и списков основных типов есть встроенная поддержка.

...