2014-03-03 23 views
4

創建實例我試着specFlow協助,不知道如何從表中創建類屬性。 想象我有這個類:SpecFlow協助 - 從表

public class Tracking 
{ 
    public string Category { get; set; } 
} 

public class ODARequest 
{ 
    public string Title { get; set; } 
    public string Name { get; set; } 
    public Tracking Tracking { get; set; } 
} 

我給定的情景是未來:

Scenario: Successfully create an account 
Given I have entered the following data into the ODA form: 
    | Field     | Value   | 
    | Title     | Mr    | 
    | Name     | Andy    | 
    | Tracking Category  | MDA    | 


public void GivenIHaveEnteredTheFollowingDataIntoTheODAForm(Table table) 
{ 
    var request = table.CreateInstance<ODARequest>(); 
} 

的跟蹤屬性不會被填充。任何人都知道如何在表格中描述Tracking.Category這種情況?

回答

3

我一直在打這個問題,一直在想如何去做只需一步

Scenario: Successfully create an account 
Given I have entered the following data into the ODA form: 
    |Title | Name | Category| 
    | Mr | Andy | MDA  | 

public void GivenIHaveEnteredTheFollowingDataIntoTheODAForm(Table table) 
{ 
    var request = table.CreateInstance<ODARequest>(); 
    request.Tracking = table.CreateInstance<Tracking>(); 
} 

它是如何工作: 你可以打電話「的CreateInstance」你有這麼specflow將創建您實例的每個複雜屬性。所以你可以有一個單獨的表格,其中包含不同類型的屬性。

通過這樣做,您將不需要不同的步驟和步驟之間共享數據的需要。

缺點是如果你的類有很多不同類型的屬性,你可能會得到一個巨大的表。

注意:由於@Alex M評論說,如果類具有同名的屬性,則存在風險。實際情況是,兩個實例都會得到相同的值,這是由於兩個類上的屬性名稱匹配。

+1

對於沒有跨越大量參數的表,這似乎是一個更好的選擇。但是,如果在類之間使用相同的屬性名稱,則可能會出現問題。 –

+0

你所描述的問題確實存在,謝謝你的提示。將此作爲警告添加到答案中。 – valentinvs

5

我一直沒有找到一種獲取specflow的方法來將「CreateInstance」映射到非標準的數據類型屬性。

然而,在這種情況下,你至少可以使用StepArgumentTransformation如下:

[Given(@"I have entered the following data into the ODA form:")] 
    public void GivenIHaveEnteredTheFollowingDataIntoTheODAForm(ODARequest request) 
    { 
     Assert.IsNotNull(request.Tracking); 
    } 

    [StepArgumentTransformation(@".*")] 
    public ODARequest StringToTracking(Table input) 
    { 
     return new ODARequest() { 
      Title = input.Rows.Single(row => row["Title"])["value"], 
      Name = input.Rows.Single(row => row["Name"])["value"], 
      Tracking = new Tracking() 
       { Category = input.Rows.Single(row => row["Field"] == "Tracking Category")["Value"] } 
      }; 
    } 

隨着一點點的工作,你可以整理的stepargumenttransformation爲接受每個參數爲可選的(而不是「單() 「如果省略則拋出)。

我覺得真的應該是一個更好的方式來做到這一點,更像是你原來的建議代碼。 希望這是有幫助的。

+0

'StepArgumentTransformation'確實不*使用'CreateInstance'或'CreateSet'。它僅*用於將規範值轉換爲明確定義的步驟方法參數,例如, 'public void GivenSomething(MyType foo)' – nathanchere

+0

@nathanchere我沒有在我的答案中使用CreateInstance,並指出我的代碼與問題中的代碼不相似。我建議的答案有問題嗎? – perfectionist

2

不修改specflow幫助本身的另一種可能性是將子類屬性分離爲單獨的Given。 可以是按下面的例子:

Scenario: Successfully create an account 
Given I have entered the following data into the ODA form: 
| Field     | Value   | 
| Title     | Mr    | 
| Name     | Andy    | 
And the tracking info as: 
| Tracking Category  | MDA    | 

然後我的步驟定義將如下:

[Given(@"I have entered the following data into the ODA form:")] 
public void GivenIHaveEnteredTheFollowingDataIntoTheODAForm(Table table) 
{ 
    var request = table.CreateInstance<ODARequest>(); 
    ScenarioContext.Current.Set(request, "request"); 
} 
[Given(@"the tracking info as:")] 
public void GivenTheTrackingInfoAs(Table table) 
{ 
    var request = ScenarioContext.Current.Get<ODARequest>("request"); 
    request.TrackingFields = table.CreateInstance<Tracking>(); 
} 

否則可能性有助於specflow協助發展。