iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 10
1
Software Development

【Unit Test】Unit Test with C#系列 第 10

【Day10】解除依賴:Stub之一

  • 分享至 

  • xImage
  •  

Unit test的名稱,就是單元測試,什麼是單元呢?一個一個小個體就可以視為單位。這樣的小個體有什麼好處?除了可以鎖定問題的所在(最主要的功能,debug最怕的是不知道bug在哪邊 QQ),也可以讓測試可以更容易的使用我們可以控制的「變數」。
為什麼呢?因為個體小,我們很容易把它包起來,就好像小時候堆的沙堡,沙堡小小的,做個護城河很容易,但是現實的城堡,光是用挖土機挖就要幾天幾夜...


Stub(樁)是一個減少外部依賴的一個方法,藉由interface(接口)的轉移,使原本依賴於外在參數變成某個虛擬的參數。就好像我們的範例,原本是要從外部取得檔案,並擷取它的名稱,這樣一來一往,花費極大的時間,更別說還要實作出這些功能。所以就需要把所有東西進行模擬化。這樣有點像是訓練飛行員的方式,不可能一下子就要他上飛機坐在駕駛艙內。會先去在模擬機器上,模擬各種飛行情況,如晴天、雨天,再根據給予的情況進行飛行操作。所以這種模擬的情況可以視為一個stub的運用。
在程式裡面,我們要做一個「模擬的駕駛艙」,裡面包圍著模擬的場景,而我們在裡面操作;所以我們要把程式碼改寫成被各種「interface」包圍著,而這些interface可以輕易的被轉換成各種狀況。我們不必管要如何接外面的資料,甚至駕駛艙外面的天氣怎樣,我們都不用知道,只要interface給我們天氣情境,我們根據這樣的情境反應。

至於怎麼做呢?
首先改寫LogAnalyer(新的範例寫在LearningUT的「Day10_LogAnalyer」)

先製作一個interface,也就是名為IEtensionManagerinterface,並且幫這個interface實體化一個參數。這個參數manager帶著原本interface的功能,也就是測試「是否為log」檔的功能。
接著我們測試的對象(arrange)就是Day10_LogAnalyzer,增加建構子,讓一開始就建立manager。然後撰寫功能IsValidLogFileName(),讓它檢測帶入的檔名是否符合規則!

class Day10_LogAnalyzer
{
    private IExtensionManager manager;   
    public Day10_LogAnalyzer(IExtensionManager mgr)
    {
        manager = mgr;
    }

    public bool IsValidLogFileName(string fileName)
    {
        return manager.IsValid(fileName);
    }
}
//interface: define an adapter.
public interface IExtensionManager
{
    bool IsValid(string fileName);
}

主要功能寫完了,接著是測試功能。
而測試的寫在「Day10_LogAnalyerTest」。
首先從上一段的interface在這邊被實現,名稱為 FakeExtensionManager,裡面包含了一個新參數WillBevalid,這邊可以管理我們要傳的值是true還是false。這就是我們控管的駕駛艙天氣(Stub)。
在測試的執行方法中IsValidFileName_NameSupportedExtension_ReturnsTrue(),呼叫了我們接口,並且設定回傳值為true。這就是我們準備回傳的stub。
接著在初始化Day10_LogAnalyzer,也把stub帶入,帶入後執行測試、檢查檔案名稱、判斷是否為true

[TestFixture]
public class Day10_LogAnalyzer_Test
{
    [Test]
    public void IsValidFileName_NameSupportedExtension_ReturnsTrue()
    {
        //func: put data to stub.
        FakeExtensionManager myFakeManager = new FakeExtensionManager();
        myFakeManager.WillBeValid = true;

        Day10_LogAnalyzer log = new Day10_LogAnalyzer(myFakeManager);
        bool result = log.IsValidLogFileName("test.TEST");
        Assert.True(result);
    }

    internal class FakeExtensionManager : IExtensionManager
    {
        public bool WillBeValid = false;
        public bool IsValid(string filename)
        {
            return WillBeValid;
        }
    }
}

這樣簡單的接口應用就產生了,我們只要動到FakeExtensionManager,就可以簡單的修改資料,決定回傳值為何。
接著就是比對(assert)看是否正常。


後記:
鬧了烏龍,以為自己的程式莫名的消失了,害我很緊張,想說這篇打到一半要重打了。
把虛擬機打開,赫然發現...原來我的git只有commit,沒有push到Github上,一直以為丟上去了(暈倒)


上一篇
【Day9】解除依賴
下一篇
【Day11】去除依賴之二-Stub 2
系列文
【Unit Test】Unit Test with C#31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言