2016-02-29 28 views
0

我正在为使用Cucumber(-JVM),Junit,Java 8接受XML文件(具有多达数百个字段)的应用程序创建验收测试框架。创建序列化的POJO到XML了很多使用生成器接口的类库(以避免几十建设者,并有各种各样的声明API),即:将Cucumber场景DataTable(HashMap)转换为方法调用

new Form.Builder 
    .setThisField(withThis) 
    .setThatField(withThat) 
    .build(); 

我做了这个库,因为我想在我的测试中动态生成有效的XML文件。我希望我的黄瓜情景阅读喜欢英语,所以我决定用的,而不是写类似数据表:

Given I have a form with x field 
and with y field 
and with z field 
and ... 

用50种不同的“和”线。因此,他们是这样的:

Given that I have Form B101 with the following fields: 
    | X Field  | X Value   | 
    | Y Field  | Y Value   | 
    | Z Field  | Z Value   | 

问题:

我想在黄瓜数据表中的键(也就是变成一个HashMap)映射到方法名我的建造者模式。起初我以为使用lambda表达式和方法引用可能会让我完成这个任务,但我还没有找到方法。

所以我的下一个想法是反思。我决定从在属性黄瓜数据表密钥的方法名存储映射文件,如:

//mapping.properties 
X\ Field = setXField 
// the \ after X is to escape the space 

我遇到了一个问题,但:有的在黄瓜数据表的字段映射到深层嵌套字段(由于XML模式)在我的XML数据绑定库中。例如:

“X字段”嵌套在A字段中。所以在我的测试方法,我需要做的:

AField aField = new AField(new XField()); 

但随着Java反射,你需要知道的事实之前,参数的数据类型(或因此我认为)。例如,如果我想找出什么参数类型与方法有关:

Class[] paramString = new Class[1]; 
paramString[0] = AField.class; 
// So I need to know before the fact that methodName (below) has a parameter 
// of type AField in order to .... get the parameter types of methodName. 


// this is legal because a method with methodName exists and it takes 
// one parameter with type AField. 
Class[] parameterTypes = 
    formB.getClass().getMethod(methodName, paramString).getParameterTypes(); 

// this is not legal. no method named methodName which doesn't 
// take parameters exists 
Class[] parameterTypes = 
    formB.getClass().getMethod(methodName).getParameterTypes(); 

我相信我能找到一种解决方法,但最终好像我要下去了“哈克'路径。有没有更好的方法来解决这个问题?还是我在“正确”的道路上?

+0

你讲一个Ø很多关于您的实现。你能分享更多关于你的问题吗?我感觉你以一种不擅长的方式使用黄瓜。但是一个具体的例子可能会更好地理解你的目标。 –

+0

@ThomasSundberg按问题你是指我正在测试的应用程序?基本上我正在测试一个将接受XML文件的Web服务。我构建了一个工具来动态生成xml文件。其中一些XML文件有125多个字段,我需要测试的业务规则有25个不同的字段。所以我需要在黄瓜的每个XML文件中表达我想要的数据。我认为数据表是最明智的解决方案,而不是a)在黄瓜场景中有100行b)表示100个字段值的哈希短手。 – douglas

+0

@ThomasSundberg此外,我无法更改应用程序以将XML文件分解为更小的子XML文件。 – douglas

回答

1

在引发主持人愤怒的风险中(明确的答案是首选链接),我会指出你的这个link。以获取列表的HashMap的考虑[这]

编辑

下面是相关的部分从引用链接的提取物。

将两列表转换为地图。

Feature: Cucumber can convert a Gherkin table to a map. 
    This an example of a simple price list. 

    Scenario: A price list can be represented as price per item 
    Given the price list for a coffee shop 
     | coffee | 1 | 
     | donut | 2 | 
    When I order 1 coffee and 1 donut 
    Then should I pay 3 

,代码:

package se.thinkcode.steps; 

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

import java.util.Map; 

import static org.hamcrest.CoreMatchers.is; 
import static org.junit.Assert.assertThat; 

public class SimplePriceList { 
    private Map<String, Integer> priceList; 
    private int totalSum; 

    @Given("^the price list for a coffee shop$") 
    public void the_price_list_for_a_coffee_shop(Map<String, Integer> priceList) throws Throwable { 
     this.priceList = priceList; 
    } 

    @When("^I order (\\d+) (.*) and (\\d+) (.*)$") 
    public void i_order_coffee_and_donut(int numberOfFirstItems, String firstItem, 
      int numberOfSecondItems, String secondItem) throws Throwable { 

     int firstPrice = priceList.get(firstItem); 
     int secondPrice = priceList.get(secondItem); 

     totalSum += firstPrice * numberOfFirstItems; 
     totalSum += secondPrice * numberOfSecondItems; 
    } 

    @Then("^should I pay (\\d+)$") 
    public void should_I_pay(int expectedCost) throws Throwable { 
     assertThat(totalSum, is(expectedCost)); 
    } 

} 
+0

我同意MikeJRamsey56。 BeanUtils是将你获得的Map 转换为数据结构的“更好的”方法。 – Arman

+0

我同意你的观点 - 根据SO标准,这显然是一个糟糕的答案。这是“仅链接”的答案,您应该将目的地页面的要点写入您的答案 - 否则可能会被关闭。 –

+0

@AleksG我哭了“叔叔!”。谢谢你提醒我改进答案。当时我太忙了,只是想给OP一个线索。当时可能应该是一个评论。 – MikeJRamsey56