D-02-驗證結果 ? ExpectedObjects

如何驗證結果

在學會如何Mock介面後,接下來處理的問題就是複雜的類別要怎麼來驗證,當然可以透過JSON的序列化及反序列化來驗證結果對不對,但是如果關注的點是只有特殊的幾個屬性呢,所以今天介紹ExpectedObjects來使得驗證結果不是一件難事。

驗證結果

「前輩,我要如何處理複雜型別的驗證阿。」
在了解BDD之後並開始寫測試案例以及處理模擬資料後小光又遇上一個問題,就是複雜型別的驗證。
「恩我遇到的問題試不知道該如何驗證返還資料試陣列的方法。」
聽到大頭這麼說,小光做動作示意是不是該去找老K了解一下這部分有甚麼方法可以處理,這時大頭也點點頭,但是在這同時老K也從遠方走了過來。
「我在想阿,你們是不是應該遇到該如何處理驗證的動作了阿。」
這時大頭跟小光互看一眼並且對著彼此笑了起來。
「那我們就從基礎開始介紹如何處理驗證資料吧。」

Assert

首先介紹的是,Microsoft.VisualStudio.TestTools.UnitTesting中的Assert,這是最基本的驗證工具可以做一些簡單的驗證。其驗證的方法如下。

var actual = _current.Get<int>("Result");
Assert.AreEqual(expected, actual);

基本上可以透過這個來做簡單的驗證,而且只能驗證基礎型別,所以我們繼續往下看,不過想要了解有哪些方法可以用可以參考C#,又來找你玩了! – MSTest 的 Assert 提供了哪些 method?

TechTalk.SpecFlow.Assist

原則上基礎的型別我們透過Assert可以驗證,所以接下來我們來處理類別class的驗證,這邊我們使用specflow的元件來驗證,首先我們可以在feature內這樣寫。

Then the result should be
| Name | Age |
| 大頭 |  20 |

然後要處理這類強行別的驗證則使用下列語法。

[Then("the result should be")]
public void ThenTheResultShouldBe(Table expect)
{
    var actual = _scenarioContext.Get<UserInfo>("Result");
    expect.CompareToInstance(actual);
}

如果說今天要驗證的資料是陣列的話,我們的測試案例調整如下。

Then the result should be
| Name | Age |
| 大頭 |  20 |
| 小光 |  15 |
| 老K  |  40 |

然後要處理驗證則使用下列語法。

[Then("the result should be")]
public void ThenTheResultShouldBe(Table expect)
{
    var actual = _scenarioContext.Get<UserInfo>("Result");
    expect.CompareToSet(actual);
}

所以針對強行別的驗證就是在feature傳入Table,然後在程式碼裡面用CompareToInstance或是CompareToSet來驗證。不過這邊的物件是會比較所有的變數,如果只針對物件的特定變數則要使用下面的套件。

ExpectedObjects

接下來要介紹這個套件可以更進一步驗證物件的某些屬性,所以首先先安裝該套件進來。

dotnet add package ExpectedObjects

接下來延續上述的例子,我們可以將程式碼改成下列內容。

[Then("the result should be")]
public void ThenTheResultShouldBe(Table expect)
{
    var actual = _scenarioContext.Get<UserInfo>("Result");
    expect.CreateInstance<UserInfo>().ToExpectedObject().ShouldEqual(actual);
}

如此就算是某屬性錯誤時錯誤訊息也會特別說明是哪個屬性不同,當然他也可以用在陣列上,如下所示。

[Then("the result should be")]
public void ThenTheResultShouldBe(Table expect)
{
    var actual = _scenarioContext.Get<UserInfo>("Result");
    expect.CreateSet<UserInfo>().ToExpectedObject().ShouldEqual(actual);
}

當然他的功用並不只這樣,他還可以使用ShouldMatch方法針對部分屬性做驗證,或者是忽略某些特定屬性,如下所示。

[Then("the result should be")]
public void ThenTheResultShouldBe(Table expect)
{
    var actual = _scenarioContext.Get<UserInfo>("Result");
    expect.CreateSet<UserInfo>().ToExpectedObject(ctx => ctx.Ignore(x => x.Name)).ShouldEqual(actual);
}

後記

今天跟著大頭還有小光學習到如何處理在BDD中的最後一個步驟,也就是如何驗證預期與實際是否相符,並且了解在Specflow中檢查強行別的類別資料是否正確,最後使用ExpectedObjects來針對部分屬性做驗證。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *