• C# WPF MVVM 实战 – 2.4 单元测试


    image

    接上篇,我留到这里才介绍怎样测试,因为不会做的话也不会测做得对不对。说是单元测试的话,其实应该设计好 Model 后,定好大概 VM 内要干什么之后,马上可以动手写测试代码。

    很多公司没有规定如何测试,更加没有单元测试,也没考虑 TDD,或许是有他们的原因的,不一定是因为水平问题的,也不一定是同事能力所限。还真的有很多人,很多老开发,不愿意写测试。这测试只是一种开发方法,是其中一个而已。没有所谓绝对的最佳办法。

    我这里说的,是一些情况,你必须要这么测,才有比较好的效率,才能确保代码正确无误。

    想一想,如果你负责写模块,同时,另一位负责写 Shell,(比如用 PRISM 的 Modularity),你在没有 Shell 的情况下,点击 Debug Run 帮不了你。你的 View 全是 UserControl,你的入口,是个 IModule 的东西而且它只负责注册视图。你真要运行来看效果来「人肉」测试的话,你只能自己写一个 Shell 出来(?!),在 IModule 注册菜单后,再由 Shell 打开视图。

    一个只为测试而做的 Shell ,可能很快能写出来。同样地,一个测试项目也一样很快能写完。它们之间的分别,是测试项目能自动重复运行。

    如果 TDD 就更加不用说了。

    废话讲完。入正题。

    测试对象:ICommand 的 CanExecute

    假设,用例之一,是「在没有选择明细行前,删除行按钮禁用」。在上几篇实现了的一个功能。

    以下省略了测试描述,只含代码:

    image

    有没有选中明细行,这是视图中 DataGrid 对它 SelectedItem 属性(绑定 VM 的 CurrentRow)赋值的一个操作,可以像上面代码一样模拟它。注意,如果你 VM 构造函数,有检查参数是否为 null 然后是 null 就抛异常的话,上面代码就当然不行,要写个模拟,如下部分的做法。

    上面代码,除了 new 什么出来测以外,真正的代码只有两行,一个是为 CurrentRow 赋值,另一个是运行 CanExecute 委托让它返回 true/false。额,当然还有 assertion 啦。

    这测试,其实只是检查 { return CurrentRow != null; } 这一句委托而已,作用不大,但想象一下,如果这是 VM 包含了数据验证用了 IDataErrorInfo,测试目标是保存按钮能不能点击,那委托,就不是那么简单了。

    测试对象:ICommand 的 Execute

    假设,用例中,要求明细行内,单行中的物料栏,要能打开另一个选择窗口来选择物料

    image

    这里做了几件事,这几件事是从用例而来,是操作的顺序。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开发板玩家群 578649319
    硬件创客 (10105555)硬件创客 (10105555)

  • 相关阅读:
    Mysql 创建表时错误:Tablespace for table `tablexx` exists. Please DISCARD the tablespace before IMPORT.
    【Problem】xampp in ubuntu下命令行启动mysql报错: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/opt/lampp/var/mysql/mysql.sock' (2)
    余生,一定要找一个随时能和你聊天的人
    找个可以说话的人 不容易
    我们都应该找一个,可以一辈子陪自己说话的人
    windows下安装ubuntu
    Ubuntu 修改环境变量
    Ubuntu14.04如何备份和恢复系统
    deeplearning 源码收集
    Caffe + Ubuntu 14.04 64bit + CUDA 6.5 配置说明2
  • 原文地址:https://www.cnblogs.com/leptonation/p/2567387.html
Copyright © 2020-2023  润新知