2016-02-29 62 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