cucumber-jvm版本3替代设计模式,用于简单表格到Map 手术

问题描述 投票:1回答:1

我正在探索在cucumber-jvm:3.0.0中引入的新io.cucumber.datatable.DataTable支持。我安装了cucumber-jvm:3.0.2。

我现有的cucumber-jvm:2.4.0项目使用了一个简单的设计模式,我将表传递给最后一个参数类型为Map的步骤。版本3中不再支持此行为。

所以我创建了一个测试用例来模拟这种设计模式的替代方案。它可以工作,但返回的Map是不可修改的。我解决了它,但有两个问题:

  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 - Convert DataTable to single object using asMap()。我确实实现了这个解决方案,但我有一些初级测试人员所以我正在寻找更简单的东西。

java design-patterns cucumber-jvm
1个回答
1
投票

您可能会发现这种模式更符合您的喜好:

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变成地图。我们使用.putAlladdress中的所有字段复制到addressMap中。

address是不可变的,以防止通过具有副作用的方法修改原始输入。当稍后使用原始输入进行断言时,这是一种有用的机制。除非明确复制了对象,否则您可以依赖它未被修改的事实。这使代码更容易阅读。

我现有的cucumber-jvm:2.4.0项目使用了一个简单的设计模式,我将表传递给最后一个参数类型为Map的步骤。版本3中不再支持此行为。

仍然支持此行为。是什么让你认为不是?

private final DataTableTypeRegistry registry = new DataTableTypeRegistry(Locale.ENGLISH); private final TableConverter converter = new DataTableTypeRegistryTableConverter(registry); private static final类型MAP_OF_STRING_TO_STRING = new TypeReference>(){}。getType();

你这里不需要这个。看看TypeRegistryConfigurer。但请记住,基本类型的地图和列表已经建立了支持。

© www.soinside.com 2019 - 2024. All rights reserved.