接上篇,我留到这里才介绍怎样测试,因为不会做的话也不会测做得对不对。说是单元测试的话,其实应该设计好 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 会是一个解脱,一部分解脱。下回继续。

我在这群里,欢迎加入交流:
开发板玩家群 578649319
硬件创客 (10105555)

转载于:https://www.cnblogs.com/leptonation/archive/2012/06/28/2567387.html

C# WPF MVVM 实战 – 2.4 单元测试相关推荐

  1. C# WPF MVVM 实战 – 3 – 树结构

    树结构放在 WPF ,有大家熟悉的 TreeView.Menu / MenuItem 等等,自定义的话它是 HierarchicalDataTemplate. 用上 MVVM 模式,视图与数据分离,意 ...

  2. C# WPF MVVM项目实战(进阶②)

    这篇文章还是在之前用Caliburn.Micro搭建好的框架上继续做的开发,今天主要是增加了一个用户窗体ImageProcessView,然后通过Treeview切换选择项之后在界面显示不同效果的图片 ...

  3. C# 值得永久收藏的WPF项目实战(经典)

    01 - 简介 之前也写过好多篇CM框架相关的项目实战文章,比如: C# WPF框架Caliburn.Micro快速搭建 C# WPF框架Caliburn.Micro入门实例1 C# WPF MVVM ...

  4. C# WPF MVVM模式Prism框架下事件发布与订阅

    01 - 前言 处理同模块不同窗体之间的通信和不同模块之间不同窗体的通信,Prism提供了一种事件机制,可以在应用程序中低耦合的模块之间进行通信,该机制基于事件聚合器服务,允许发布者和订阅者之间通过事 ...

  5. C# WPF MVVM模式Prism框架从零搭建(经典)

    01 - 前言 目前最新的PRISM的版本是8.1.97,本节以6.3.0.0 讲解,可以在Github上获取PRISM的源码. Prism Github地址:https://github.com/P ...

  6. WPF MVVM 弹框之等待框

    WPF MVVM 弹框之等待框 目录 一.效果 二.弹框主体改造 三.等待动画用户控件 四.弹窗 ViewModel 和帮助类的改造 五.使用方法和代码地址 独立观察员 2020年10月13日 之前写 ...

  7. C# WPF MVVM模式Caliburn.Micro框架下事件发布与订阅

    01 - 前言 处理同模块不同窗体之间的通信和不同模块之间不同窗体的通信,Caliburn提供了一种事件机制,可以在应用程序中低耦合的模块之间进行通信,该机制基于事件聚合器服务,允许发布者和订阅者之间 ...

  8. 疯狂 java轻量级框架_ViewModel从未如此清爽 - 轻量级WPF MVVM框架Stylet

    Stylet是我最近发现的一个WPF MVVM框架, 在博客园上搜了一下, 相关的文章基本没有, 所以写了这个入门的文章推荐给大家. Stylet是受Caliburn Micro项目的启发, 所以借鉴 ...

  9. WPF MVVM从入门到精通1:MVVM模式简介

    WPF MVVM从入门到精通1:MVVM模式简介 原文:WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录 ...

  10. WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍...

    WPF自学入门(十一)WPF MVVM模式Command命令 在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式.正 ...

最新文章

  1. 减少代码中该死的 if else 嵌套
  2. ITK:计算梯度各向异性扩散
  3. CUDA编程中内存管理机制
  4. 推荐一款生成SQL插入语句的软件
  5. nacos 本地测试_本地调试和服务器调试都无法连通-问答-阿里云开发者社区-阿里云...
  6. linux /etc/group文件详解
  7. POJ 1721 CARDS(置换群)
  8. rose怎么把两个mdl弄在一起_面试美敦力,HR要我降Title,怎么办?(上)
  9. mysql更改密码_Mysql更改密码、连接mysql、mysql常用命令
  10. Keil uVision5 安装及注册有效至2032
  11. 最小二乘法曲线拟合原理
  12. 东信杯题解详细版本附带代码(还有日常琐碎bb)
  13. HDU 1429 bfs 状态压缩
  14. linux挖矿的清理工具,Linux挖矿病毒的清除与分析
  15. 修改电脑C:\User\用户名文件夹的名字
  16. 论文阅读问题总结(六):Meta-Learning with Domain Adaption for Few-shot Learning Under Domain Shift
  17. 物联网应用之现代档案馆环境智能化监控系统解决方案
  18. getopt.h及相应的函数
  19. C++ L1-034. 点赞
  20. HP电脑恢复系统(一键还原)

热门文章

  1. 阿里P8大牛匠心独运,用图解的方式让繁杂的计算机网络一目了然
  2. linux内核协议栈 TCP选项之SACK选项的接收Ⅰ
  3. Android 支付宝开发错误总结
  4. html 链接excel表格,excel表格超链接设置
  5. Spring单例模式的一次失败经历和总结
  6. 图片实现裁剪功能vue-img-cutter
  7. 2021-04-26 PNP三极管
  8. Android以太网卡配置启动流程和双网卡同时支持的实现
  9. smartbi试用体验
  10. 机器学习数学篇—基础数学知识清单