關於 Microsoft Fake 的使用情境與除錯

RojerChen.2017.06.03

最近在看這篇文章的時候,遇到了一些 Fake 的問題,因此紀錄一下

[30天快速上手TDD][Day 7]Unit Test - Stub, Mock, Fake 簡介


※使用 Fake 的情境

假設每到星期五的時候就要來點折扣,所以我需要一個功能來去判斷今天是不是星期五,如果是的話就需要特價。
public class eCommerical
{
    public bool isTimeToDiscount()
    {
        bool result = DateTime.Today.DayOfWeek == DayOfWeek.Friday;
        return result;
    }
}
在寫測試的時候我可能就會這樣寫,只不過這樣寫的問題在於,如果今天是星期五執行測試,那會通過沒有問題,但是如果是非星期五的時候,執行測試就會失敗。
[TestMethod]
public void Test_Is_Time_To_Discount()
{
    //arrange
    bool expected = true;
    MyLibrary.eCommerical eCom = new eCommerical();
 
    //act
    bool actual = eCom.isTimeToDiscount();
 
    //assert
    Assert.AreEqual(expected,actual);
}
為了要解決這樣的問題,比較簡單的做法就是把今天是星期幾當作參數傳遞近來,然後再調整一下測試,這樣就不會因為星期幾個時候跑測試而發生錯誤了。
public bool isTimeToDiscount(DateTime today)
{
    bool result = today.DayOfWeek == DayOfWeek.Friday;
    return result;
}
[TestMethod]
public void Test_Is_Time_To_Discount()
{
    //arrange
    bool expected = true;
    MyLibrary.eCommerical eCom = new eCommerical();
 
    //act
    bool actual = eCom.isTimeToDiscount(new DateTime(2017,6,2));
 
    //assert
    Assert.AreEqual(expected, actual);
}
可是瑞凡,程式已經上線了,而且這樣修改幅度很大,有甚麼方法可以做呢?這個時候可以透過 Isolation Framework 來輔助,使用 VS 企業版 可以透過  Microsoft  Fake 來協助建立假物件。

※使用方式

使用時其實相當簡單,在測試專案中只需要把有參考的物件點選右鍵,選擇 Add Fake Assembly 即可 (此功能只有 VS 企業版才有此功能)。



因為本專案中有用到 system.datetime,需要需要額外將 System 建立假物件,因為使用的 datetime 是在 mscorlib 所以一併會建立 mscorlib.fake

建立完畢之後修改一下測試案例,改成這樣子
[TestMethod]
public void Test_Is_Time_To_Discount()
{
    using (ShimsContext.Create())
    {
        //arrange
        bool expected = true;
        MyLibrary.eCommerical eCom = new eCommerical();
 
        System.Fakes.ShimDateTime.NowGet =
            () =>
            {
                return new DateTime(201762);
            };
 
        //act
        bool actual = eCom.isTimeToDiscount();
 
        //assert
        Assert.AreEqual(expected, actual);
    }
}
通常改成這樣子之後,程式還是會有問題,因為找不到 ShimDateTime,大概會出現下面這樣的錯誤訊息

Severity Code Description Project File Line Suppression State
Error CS0234 The type or namespace name 'ShimDateTime' does not exist in the namespace 'System.Fakes' (are you missing an assembly reference?)

我的解決方式是先修改 mscorlib.fakes,修改成下面這個樣子,然後把 system.fakes 移除然後再重新建立
<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
  <Assembly Name="mscorlib" Version="4.0.0.0"/>
  <StubGeneration>
    <Clear />
    <Add Namespace="System.IO!"/>
  </StubGeneration>
</Fakes>
處理後就不會有上述 ShimDateTime 的問題了。
這樣日後執行測試的時候,在跑 Datetime.Today 的時候,就可以依據我們測試案例中所帶的日期來去執行了。

※參考文章

[30天快速上手TDD][Day 7]Unit Test - Stub, Mock, Fake 簡介

Microsoft Fakes 中的程式碼產生、編譯和命名慣例

Isolating Code Under Test with Microsoft Fakes

Microsoft Fakes 入門

    Blogger Comment

0 意見: