代码之家  ›  专栏  ›  技术社区  ›  MikeJRamsey56

cumberjvmversion3将设计模式替换为映射<String,String>操作的简单表

  •  1
  • MikeJRamsey56  · 技术社区  · 7 年前

    io.cucumber.datatable.DataTable 黄瓜中引入的支持-jvm:3.0.0。我有黄瓜-jvm:已安装3.0.2。

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

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

    1. 为什么返回的映射是不可变的?我是否忽略了一个重要的设计原则?

    代码如下:

    # 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()

    1 回复  |  直到 7 年前
        1
  •  1
  •   M.P. Korstanje    7 年前

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

    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 .

    地址 是不可变的,以防止方法修改原始输入而产生副作用。当原始输入稍后用于进行断言时,这是一种有用的机制。除非对象被显式复制,否则您可以依赖它没有被修改的事实。这使得代码更容易阅读。

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

    private final DataTableTypeRegistry registry=新建DataTableTypeRegistry(Locale.ENGLISH语言); private final TableConverter converter=new DataTableTypeRegistryTableConverter(注册表);

    TypeRegistryConfigurer