[30天快速上手TDD][Day 14]Refactoring - 驗貨
前言
在上一篇文章中,重構第五式:「給你錢,趕快做」中,重點在於如何站在當下物件的角度,去思考自身職責該處理的邏輯,並思考非自身職責的部分,該委託給哪一個物件來處理。
「只管跟它要,而不管它怎麼做」,這就是第五式的精髓。
接下來這篇文章,則是怎麼驗證委託物件給的,真的是我們要的呢?
所以這一篇文章標題,定義為「驗貨」,重構第六式:「確定對方給的,是我要的」
我們將先透過建立測試案例,來確保物件回傳的結果,是如同我們所預期。(這一篇文章的重構技巧,需要用到前面介紹的測試相關技巧)
重構第六式:確定對方給的,是我要的
在前面已經定義出來『我們要什麼,跟誰要』,接著是要確定『物流商給我們的資訊,是不是我們要的』。
怎麼確定物流商給的資訊沒錯?對啦,就是用測試啦。
正所謂羊毛出在羊身上,建立單元測試的測試案例,往往可以從一開始的整合測試案例中找到蛛絲馬跡,也就是我們一開始錄影存證的部份。
Selenium test cases 如下圖所示:
期望結果(以黑貓為例):
- 呼叫黑貓的 GetsCompanyName 方法,應該得到『黑貓』。
- 還沒呼叫黑貓計算運費前,呼叫黑貓的 GetsFee 方法,應該得到 0 。
- 當給了整合測試上的商品資訊後,呼叫黑貓的 Calculate 方法後,呼叫 GetsFee 方法,應該得到 200 。
依據測試案例,建立的單元測試程式碼如下:
/// <summary>
///GetsComapanyName 的測試
///</summary>
[TestMethod()]
public void GetsComapanyNameTest_v3()
{
BlackCat target = new BlackCat();
string expected = "黑貓";
string actual;
actual = target.GetsComapanyName();
Assert.AreEqual(expected, actual);
}
/// <summary>
///GetsFee 的測試
///</summary>
[TestMethod()]
public void GetsFeeTest_v3()
{
BlackCat target = new BlackCat();
double expected = 0F;
double actual;
actual = target.GetsFee();
Assert.AreEqual(expected, actual);
}
/// <summary>
///Calculate 的測試
///</summary>
[TestMethod()]
public void CalculateTest_v3()
{
//從整合測試的test case,來當做單元測試的test case
//arrange
BlackCat target = new BlackCat()
{
ShipProduct = new Product
{
IsNeedCool = true,
Name = "商品測試1",
Size = new Size
{
Height = 10,
Length = 30,
Width = 20
},
Weight = 10
}
};
//act
target.Calculate();
var expectedName = "黑貓";
var expectedFee = 200;
var actualName = target.GetsComapanyName();
var actualFee = target.GetsFee();
//assert
Assert.AreEqual(expectedName, actualName);
Assert.AreEqual(expectedFee, actualFee);
}
註:對Unit test還不熟的朋友,可以參考本系列前面的鐵人賽文章:[30天快速上手TDD][Day 3]動手寫 Unit Test,或是[ASP.NET]重構之路系列v5 –單元測試, Just Do It!!
建立完我們預期物流商的行為,執行一下測試的結果,得到了 9 個紅燈,得到的例外都是『System.NotImplementedException: 方法或作業尚未實作』(因為我還沒發功啊)。如下圖所示:
看到紅燈,莫急莫慌莫害怕,因為這是我們所設定這一次動作的終點線。(同時也是起點線,笑...)
慢慢地,各位讀者就會了解到,看到紅燈有種莫名的快感,只要把紅燈轉綠,就至少可以交差的感覺,更是妙不可言。
小結
雖然上面這一步碰到了 9 個紅燈,但是這個紅燈是一個很棒的里程碑,因為這是重構循環中,重要的一個紅燈。(基本上,也可以當作是 TDD 的紅燈)如下圖所示
這一個紅燈,代表了我們已經邁出了第一步:「先思考好,使用者要什麼。」 接著,不管物件怎麼設計,程式寫的多爛、多沒彈性,我們都可以確定:「眼前這爛貨或是神蹟,到底能不能滿足我們的需求」。
TDD, Agile, Scrum ,都有個重要的精神:小步前進,迅速回饋,擁抱變化,隨時調整。
相同的目標,都是做出最吻合使用者需求的軟體。任何需求的異動,架構的調整,程式的改善,都是讓系統品質更加進化的方式,只有最符合使用者需求,系統才有所謂的價值。(順便推薦一本跟這相關的好書:浮現式設計-專業軟件開發的演進本質,原文書名:Emergent Design: The Evolutionary Nature of Professional Software Development)
做再好的軟體,全世界沒人用,那就真的是一坨金子堆出來的廢物。亮晶晶,也很貴,但仍是廢物。
by the way, 眼尖的讀者朋友應該已經發現,重構系列中會開始不斷運用到本系列前面的第一大主題:測試的目的、技巧、工具與方式。這也是為什麼第一篇總綱,就先定義出 TDD 各大主題的學習順序,與實際開發時的順序不太相同。
TDD 真的不難,但相關的每一份基本功,都要夠紮實,才不會因為碰到一些門檻,就嫌棄測試無用,這實在非測試之罪啊…
blog 與課程更新內容,請前往新站位置:http://tdd.best/