2015年11月1日 星期日

NSubstitute 練習題 - 方法執行多次且回傳的值需要做改變

題目有點難定,這麼做個簡單的說明,在一個使用情境裡會使用到同個類別的同個方法多次,然後第一次執行的結果與後續幾次的執行結果會有所不同。例如在一個使用情境裡,方法裡會使用到一個物件 collection,然後會去使用另一個類別的方法做多次處理(比方說,刪除),執行第一次與後續幾次的執行就會有不同的回傳結果。

如果要對這個使用情境去做單元測試時,以上的那個執行多次的類別方法是需要被隔離,使用 NSubstitute 建立 stub 與預期回傳值,那麼應該怎麼處理呢?

 


這是上週同事向我詢問的一個問題,在印象中好像我並沒有實作過類似的操作情境,所以也對於怎麼在單元測試裡去處理這樣的狀況是有點陌生,所以找了一下相關的實作方式,最後還是在 NSubstitute 官網的說明文件裡找到方式,以下就來做說明。

 

下面的 FooContext 類別的 JustDemoProcess 方法就是我們要測試的目標,會用到有實作ICustomerService 介面的類別裡面的 SomeProcess 方法,而且會使用到兩次,兩次的回傳結果會不同,

image

以下是 FooContext 類別的 JustDemoProcess 方法裡會使用到的另一個介面定義,JsutDemoProcess 方法會去使用 SomeProcess 方法,裡面怎麼實作就不去管他

image

 

這要怎麼測試呢?

 

如果是很直覺的直接使用 NSubstitute 去建立 stub 的話,就應該會是下面的做法,以下的單元測試方法裡有使用的「AutoFixture」這個套件建立測試資料。

以下的單元測試 Arrange 內容看起來是蠻正常的,似乎都有依據實際的使用情境去做設定以及給予預期執行 ICustomerService.SomeProcess 方法的回傳結果,而且依照這個單元測試去實際執行也會得到綠燈,但是… 確有很大的問題,

image

進入偵錯模式看看 FooContext 的 JustDemoProcess 方法的執行時的內容,

image

原本預期第一次執行 ICustomerService.SomeProcess() 方法的回傳值 Customers 數量會有兩個,但是觀察偵錯模式的執行卻是看到兩次的執行回傳 Customers 數量都是一個,也就是說用 NSubstitute 所建立的兩個 stub,最後是只用到了最後所設定的。

 

應該怎麼做呢?

 

前面有說到,其實在 NSubstitute 官網的說明文件裡就有說明應該要怎麼處理,

NSubstitute: Multiple return values

image

簡體中文的說明翻翻譯:
NSubstitute完全手册(七)设置多个返回值 - 匠心十年 - 博客园

 

於是單元測試的程式內容要改成以下的方式,

image

image

進入偵錯模式觀察執行的內容

image

從上面的執行內容就可以看到第一次執行 ICustomerService.SomeProcess() 與第二次執行的回傳值就會不同了,而且是依據我們所指定的預期內容來回傳。

 


使用並且比較過多種 Mock 工具的使用,會發現到 NSubstitute 的確是比其他一些 Mock 工具還要來得方便與簡易。

 

參考連結

NSubstitute: Multiple return values

NSubstitute完全手册(七)设置多个返回值 - 匠心十年 - 博客园

 

相關連結

Github - AutoFixture/AutoFixture

 

延伸閱讀

Mocking: why we picked NSubstitute - Adaptive

 

以上

沒有留言:

張貼留言

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。