C# WPF MVVM 實戰 – 2.4 單元測試

來源:互聯網
上載者:User
文章目錄
  • 測試對象:ICommand 的 CanExecute
  • 測試對象:ICommand 的 Execute
  • 其他
  • 總結

接上篇,我留到這裡才介紹怎樣測試,因為不會做的話也不會測做得對不對。說是單元測試的話,其實應該設計好 Model 後,定好大概 VM 內要幹什麼之後,馬上可以動手寫測試代碼。

很多公司沒有規定如何測試,更加沒有單元測試,也沒考慮 TDD,或許是有他們的原因的,不一定是因為水平問題的,也不一定是同事能力所限。還真的有很多人,很多老開發,不願意寫測試。這測試只是一種開發方法,是其中一個而已。沒有所謂絕對的最佳辦法。

我這裡說的,是一些情況,你必須要這麼測,才有比較好的效率,才能確保代碼正確無誤。

想一想,如果你負責寫模組,同時,另一位負責寫 Shell,(比如用 PRISM 的 Modularity),你在沒有 Shell 的情況下,點擊 Debug Run 幫不了你。你的 View 全是 UserControl,你的入口,是個 IModule 的東西而且它只負責註冊視圖。你真要運行來看效果來「人肉」測試的話,你只能自己寫一個 Shell 出來(?!),在 IModule 註冊菜單後,再由 Shell 開啟視圖。

一個只為測試而做的 Shell ,可能很快能寫出來。同樣地,一個測試專案也一樣很快能寫完。它們之間的分別,是測試專案能自動重複運行。

如果 TDD 就更加不用說了。

廢話講完。入正題。

測試對象:ICommand 的 CanExecute

假設,用例之一,是「在沒有選擇明細行前,刪除行按鈕禁用」。在上幾篇實現了的一個功能。

以下省略了測試描述,只含代碼:

有沒有選中明細行,這是視圖中 DataGrid 對它 SelectedItem 屬性(綁定 VM 的 CurrentRow)賦值的一個操作,可以像上面代碼一樣類比它。注意,如果你 VM 建構函式,有檢查參數是否為 null 然後是 null 就拋異常的話,上面代碼就當然不行,要寫個類比,如下部分的做法。

上面代碼,除了 new 什麼出來測以外,真正的代碼只有兩行,一個是為 CurrentRow 賦值,另一個是運行 CanExecute 委託讓它返回 true/false。額,當然還有 assertion 啦。

這測試,其實只是檢查 { return CurrentRow != null; } 這一句委託而已,作用不大,但想象一下,如果這是 VM 包含了資料驗證用了 IDataErrorInfo,測試目標是儲存按鈕能不能點擊,那委託,就不是那麼簡單了。

測試對象:ICommand 的 Execute

假設,用例中,要求明細行內,單行中的物料欄,要能開啟另一個選擇視窗來選擇物料。

這裡做了幾件事,這幾件事是從用例而來,是操作的順序。target.ItemCodeSelectionCommand 沒有必要 Execute,運行了也只是有個空白視窗,標題是 Mock Empty Window 的而已,寫這樣純粹為示範類比類用到依賴注入上。

這測試能通過,但或許會有錯誤資訊,不過你看看就知道是 BackgroundWorker 的事,我不作解釋了,它跟這裡無關。

其他

額,其他我不說了。測屬性沒什麼好說,特別是在這裡沒資料驗證的情況下。

總結

我覺得測試中,MVVM 跟其他的,不一樣的地方就是這個 ICommand。上面寫了它兩方面的測試運作。我就單單寫這部分算了。

測試中,沒有調用採購訂單的視圖,連快顯視窗也是假的,這測試,要測的是 ViewModel 本身。MVVM 在單獨測試有優勢,就是 ViewModel 它自己能做到完全與 View 隔開,單獨運行。好處是:

  1. 外殼沒寫就已經開始寫和測試 ViewModel
  2. 快顯視窗沒寫也可以寫和測試 ViewModel
  3. 減少了依賴,發生錯誤時,尋找的範圍只限於 ViewModel 本身
  4. 每次改動後,重複測試,能確保 ViewModel 按照原定的行為跑

至於 Model 呢,Model 本身只是個放值的容器,除 get /set 外沒有任何東西,如果 EF 等等的 ORM 它更是自動產生,我認為沒必要分離出來,它錯的機會低,而且分出來也有相當大的工作量。

再說一篇這隻是其中一個方法,再說這做法與外面、書本上說的不一樣,有點歪曲了的做法。對我管用。實際用不用,請自行考慮。

採購訂單樣本,到此結束。往後的是,MVVM 應用時的各種情況,下一篇將會是樹結構在 MVVM 的綁定。

樹結構很有趣,很多演算法都跟它有關,它也隨處可見,比如菜單,比如產品結構 BOM 、組織架構等等。雖然有趣,但用起來痛苦,過往你試過寫代碼曆遍 node 找一個元素,然後一堆 boxing / unboxing,你懂的。用 MVVM 會是一個解脫,一部分解脫。下回繼續。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.