我正在探索在cucumber-jvm:3.0.0中引入的新io.cucumber.datatable.DataTable支持。我安装了cucumber-jvm:3.0.2。
我现有的cucumber-jvm:2.4.0项目使用了一个简单的设计模式,我将表传递给最后一个参数类型为Map的步骤。版本3中不再支持此行为。
所以我创建了一个测试用例来模拟这种设计模式的替代方案。它可以工作,但返回的Map是不可修改的。我解决了它,但有两个问题:
这是代码:
# 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()。我确实实现了这个解决方案,但我有一些初级测试人员所以我正在寻找更简单的东西。
您可能会发现这种模式更符合您的喜好:
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中不再支持此行为。
仍然支持此行为。是什么让你认为不是?
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。但请记住,基本类型的地图和列表已经建立了支持。