在寫程式的時後,常常會用到DateTime.Now來判斷目前時間,依照時間邏輯去撈取不同的資料,但碰到單元測試要驗證的時候就是個大麻煩,因為DateTime.Now每次執行的時候時間都會改變,所以以前的做法都是這樣
1 | public static class SystemTime |
然後在在程式碼裡面使用的時候不直接使用DateTime.Now,改用SystemTime.Now
1 | void Main() |
之後單元測試驗證時,動態去改寫SetCurrentTime,就能確保拿到自己要的時間
1 | SystemTime.SetCurrentTime = () => new DateTime(2016,10,17,12,0,0); |
雖然這樣可以解決問題沒錯,但實在太麻煩,為了單元測試要多寫一堆Code之外,System底下很多東西有用到時,都要因為可以單元測試的關係而擴充出來。
還好之後有找到方法可以針對DLL做Fake,讓我們可以繼續安心使用DateTime.Now之餘,單元測試也能指定時間,接下來就來實作一下這個步驟
首先在單元測試的專案對參考的組件System按下右鍵,新增Fake物件
[![](https://4.bp.blogspot.com/-2CmHnA1rUMA/WARsswfjOPI/AAAAAAAAIBI/HGzYnnuIOzM6DuGEl8psJIIA4EtBmutgQCLcB/s1600/1.png)](https://4.bp.blogspot.com/-2CmHnA1rUMA/WARsswfjOPI/AAAAAAAAIBI/HGzYnnuIOzM6DuGEl8psJIIA4EtBmutgQCLcB/s1600/1.png)接著就會跑出Fake資料夾
[![](https://3.bp.blogspot.com/-QhvjMs19Dr4/WARtB33gWvI/AAAAAAAAIBM/ptqbpm0CKTgbi5C8CWZY3DjWbmykiJa4gCLcB/s1600/1.png)](https://3.bp.blogspot.com/-QhvjMs19Dr4/WARtB33gWvI/AAAAAAAAIBM/ptqbpm0CKTgbi5C8CWZY3DjWbmykiJa4gCLcB/s1600/1.png)接著只要在單元測試的地方寫如此寫,就能設定DateTime.Now應該回傳的時間了```csharp
[TestMethod]public void 取得現在時間() { using (ShimsContext.Create()) { System.Fakes.ShimDateTime.NowGet= () => { return new DateTime(2016, 9, 25); }; //arrange var expected = new DateTime(2016, 9, 25); //act var actual = DateTime.Now; //assert Assert.AreEqual(expected, actual); } }
```
補充2017/01/24
單元測試Fake的功能,以Visual Studio 2015來說只有Enterprise版本才有支援,所以使用的時候請特別小心,像今天公司因為授權費的關係,要求調降成Professional,之前有用到Fake的地方就都測不過了,還請特別注意
各版本比較 : Compare Visual Studio 2015 Offerings
參考文章
[Huan-Lin - Microsoft Fakes 入門](http://huan-lin.blogspot.com/2012/10/microsoft-fakes.html)