網頁

2015年9月1日 星期二

NSubstitute 練習題 - void 不回傳值方法但有使用到 out 參數

嗯…… 好久沒有寫文章,再次寫文章的題目卻讓人搞不太清楚,簡單來說就是看下面圖會比較清楚,

image

不要問為何會有這樣的程式,又為何要這麼樣設計與使用,那個不是重點,重點在於怎麼去對這一段程式去做測試。

 


計算兩點座標距離的程式在 GeographyService 的 ValidateDistance 方法裡,

介面:IGeographyService

image

實作:GeographyService

image

如果兩點座標距離超過 20000 公尺,就會拋出 InvalidOperationException 例外,不超過的話則是把計算後的距離放到 out distance 參數當中。

這裡的計算兩個座標點的距離會使用到 System.Device 參考,然後 GeoCoordinate 類別的擴充方法 GetDistanceTo() 的命名空間則是在 System.Device.Location,

SNAGHTML8d612d

MSDN - System.Device.Location 命名空間 ()

MSDN - GeoCoordinate.GetDistanceTo 方法 (System.Device.Location)

 

而 SampleContext 類別的 FooMethod 方法會使用 GeographyService 的 ValidateDistance() 方法,

image

主要是測試 SampleContext.FooMethod 對於兩個座標點計算距離之後的處理,對於原本 GeographyService.ValidateDistance() 方法的實作內容並不是目前要測試的主要目標,所以這邊就會使用 NSubstitute 來建立 IGeoprahpyService 的 Stub 物件。

下面的寫法看起來沒有什麼問題,

image

而且測試也會過

image

但是實際上因為沒有真正的執行到 GeographyService.ValidateDistance() 實作裡,所以不會真的去計算兩個座標點的距離,所以上面的測試所使用到的 distance 都一直是零(int 的初始值)。

 

怎麼測?

問題來了,一個 void 修飾方法是不會有回傳值,而且把值給傳遞到使用端的是透過 out 參數,這樣的情況要怎麼在單元測試方法裡用 NSubstitute 去完成測試呢?

 

直接看 NSubstitute 的文件,會用到以下的兩篇文件裡的方式,

NSubstitute: Callbacks, void calls and When..Do

NSubstitute: Setting out and ref args

將原本的方法依據上面兩篇文件說明的方式做了修改。因為是修飾詞為 void 的不回傳值的方法,所以也無法使用 Returns(),但是有個 out 參數要把計算後的距離給傳遞出來,所以就使用了 When … Do… 方法,然後在 Do… 這裡 out 參數要傳遞出來的值。

image

大家對於上面 Do…  裡面的 x[4] 會有點質疑,為什麼是用「4」呢?
其實那個「4」所指的是方法簽章裡的參數索引數,由零開始算,而 ValidateDistance() 方法簽章的索引位置為四的就是 out int distance 這個參數。

如果方法簽章裡有多個 out 或是 ref 參數也是使用相同的做法,可以指定多個參數,不過要指定好參數的索引位置。

以偵錯模式進入單元測試裡,實際去看看測試執行的時候是不是就是真如我們所指定的,out int distance 是傳遞指定的「500」?

進入偵錯模式之後可以觀察到 out distance 參數的確是使用我們再單ˋ原測試裡所指定的 500.

image

其他針對不同 distance 決定不同的 message 情境也使用相同的情境一併完成單元測試,

image

image

image

 

看起來這邊好像都已經把這邊的使用情境都測試到了,不過還是有一個部分忘記測了,那就是兩個座標點位置的距離如果超過 20000m 的時候就會拋出例外,這個部分還是需要被測試到,至於怎麼測這個例外呢?

其實做法跟這一篇所講的是差不多,只是有一點點不同,不過這個部分就下一篇再來說吧。

 

參考連結

MSDN - System.Device.Location 命名空間 ()

MSDN - GeoCoordinate.GetDistanceTo 方法 (System.Device.Location)

NSubstitute: Callbacks, void calls and When..Do

NSubstitute: Setting out and ref args

NSubstitute完全手册索引 - Dennis Gao - 博客园

[C#.NET] 單元測試 Mock Framework - NSubstitute - 余小章 @ 大內殿堂- 點部落

 

想要更加瞭解測試與敏捷開發,就一定要關注 91 哥的「91 敏捷開發之路」Facebook 粉絲專頁
https://www.facebook.com/91agile

 

以上

1 則留言: