.NET Core TDD 前传: 编写易于测试的代码 -- 依赖项
第1篇: 讲述了如何创造"缝". "缝"(seam)是需要知道的概念.
第2篇, 避免在构建对象时写出不易测试的代码.
本文是第3篇, 讲述依赖项和迪米特法则.
迪米特法则 (Law of Demeter)
还是使用建造汽车的例子. 生产汽车的时候需要轮胎, 组装时需要什么型号的轮胎, 就请求该型号的轮胎, 然后相关人员会从库房把该型号的轮胎送到产线用于组装.
我相信很少有汽车厂会这样做: 生产汽车时, 汽车组装工拿着库房的钥匙, 自己去库房从各种各样的轮胎中找所需要的型号..
这就是违反迪米特法则的一个例子.
迪米特法则大概的意思是: "只访问你自己创建的对象, 或者作为参数传给你的对象. 不要通过其它对象间接的访问对象"
用一句话归纳迪米特法则就是: "只与直系朋友交谈, 不要和陌生人交谈".
注意: 迪米特法则其实并不算严格的法则, 它只是一个非常有益的指导性原则.
存在的问题
用代码形容上面的例子就是:
这违反了迪米特法则, 导致了以下问题:
造成了BenzCar和Warehouse以及MichelinTire之间的紧耦合, 而实际上BenzCar只需要MichelinTire.
测试时, 设置会很麻烦. 代码里Warehouse是直系朋友, MichelinTire是陌生人. 我们需要为Warehouse和MichelinTire同时设置测试替身.
真正需要的依赖项没有明确在构造函数里定义. 这里Warehouse相当于是一个容器, 测试时, 我们可能会不知道要为Warehouse里的哪个东西做测试替身.
危险信号
下列写法可能意味着您的代码违反了迪米特法则:
代码里有这样的调用: "warehouse.getTire.getMichelinTire", 有一连串的点".". 但是有时候这样做是可以的, 例如流畅(fluent)形式的建造者模式就可以, 因为fluent接口通常会返回对象本身, 然后再去使用该对象.
依赖于容器. 例如把 IocContainer作为依赖注入使用.
依赖项的名称为XxxContext, XxxContainer, XxxEnvironment, XxxManager, XxxServiceLocator.
测试时需要创建返回mocks的mock对象.
测试时的设置非常麻烦.
解决办法
解决办法就是遵从迪米特法则.
只注入我们直接需要的依赖项, 直接使用它们. 这样就会保证依赖项很明确, 测试的时候一眼就能看出依赖于哪些对象.
代码示例
例子一
下面这个违反了迪米特法则, 直接注入的是Warehouse, 而实际用到的却是MichelinTire:
正确的做法是, 注入直接使用的依赖项:
例子二
下面的代码也违反了迪米特法则, 它注入了一个容器类的对象:
这个ServiceLocator就相当于是一个容器. 这样用的话, 写测试的人可能根本无法知道需要使用容器里面的哪个对象.
你也许会说这样做灵活(我以前也经常这样做), 但是重构的时候, 这里很容易出错, 因为根本看不出来真正依赖的是哪个对象.
正确的做法还是应该注入直接需要的依赖项:
Law of Demeter相关的内容就简单介绍这些.
原文地址:https://www.cnblogs.com/cgzl/p/9389176.html
.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com
.NET Core TDD 前传: 编写易于测试的代码 -- 依赖项相关推荐
- .NET Core TDD前传: 编写易于测试的代码 -- 缝
有时候不是我们不想做单元测试, 而是这代码写的实在是没法测试.... 举个例子, 如果一辆汽车在产出后没完成测试, 那么没人敢去驾驶它. 代码也是一样的, 如果项目未能进行该做的测试, 那么客户就不敢 ...
- .NET Core TDD 前传: 编写易于测试的代码 -- 全局状态
第1篇: 讲述了如何创造"缝". "缝"(seam)是需要知道的概念. 第2篇, 避免在构建对象时写出不易测试的代码. 第3篇, 依赖项和迪米特法则. 本文是 ...
- .NET Core TDD 前传: 编写易于测试的代码 -- 构建对象
该系列第1篇: 讲述了如何创造"缝". "缝"(seam)是需要知道的概念. 本文是第2篇, 介绍的是如何避免在构建对象时写出不易测试的代码. 本文的概念性内 ...
- 单元测试:如何编写可测试的代码及其重要性
原文来自互联网,由长沙DotNET技术社区编译.如译文侵犯您的署名权或版权,请联系小编,小编将在24小时内删除.限于译者的能力有限,个别语句翻译略显生硬,还请见谅. 作者:谢尔盖·科洛迪(SERGEY ...
- 如何编写可测试的代码 哈利勒的方法论
Understanding how to write testable code is one of the biggest frustrations I had when I finished sc ...
- ORAN专题系列-18:5G O-RAN FrontHaul前传接口互操作性测试规范IOT概述与总体架构
前言: 前传接口(FrontHual)是传统的BBU与RU之间的接口,在O-RAN之前,前传接口虽然定义了物理连接的CPRI标准,但CPRI之上承载的M plane和S/C/U plane的IQ数据, ...
- 用java写穿越火线代码_编写可测试的 JavaSript 代码
无论我们使用和Node配合在一起的测试框架,例如Mocha或者Jasmine,还是在像PhantomJS这样的无头浏览器中运行依赖于DOM的测试,和以前相比,我们有更好的方式来对JavaScript进 ...
- ORAN专题系列-19:5G O-RAN FrontHaul前传接口M Plane互操作性测试IOT规范
前言: 在<ORAN专题系列-18:5G O-RAN FrontHaul前传接口互操作性测试规范IOT概述与总体架构>阐述了5G O-RAN FrontHaul前传接口互操作性测试规范IO ...
- 《编写可测试的JavaScript代码》——1.4 小结
本节书摘来自异步社区<编写可测试的JavaScript代码>一书中的第1章,第1.4节,作者: [美]Mark Ethan Trostler 译者: 徐涛 更多章节内容可以访问云栖社区&q ...
最新文章
- 未来全球15大热门研究方向出炉!
- Docker - Tips
- Overlay 网络 — Overview
- 08-cmake语法-set()
- 初识ABP vNext(5):ABP扩展实体
- python读取word图片_Python中如何读取Word中的图片
- 【报告分享】迈向更好的教育:未来教育的技术空间研究报告.pdf(附下载链接)
- 如何利用Camtasia为视频添加注释?
- java中的控制执行流程
- cisco5525防火墙***流量分离即***和nat并存的配置方式
- HTML5响应式手机模板:h5手机抽奖游戏活动页面集合模板 HTML+CSS+JavaScript
- word制作表格并打印
- 2019软科【世界一流计算机学科排名】公布!
- Egyptian Miracle Technical Service Support
- influxDB快速入门实战教程
- 安装win7x64、x86总提示文件出错或安装大型软件出错或0x0000001a、0x0000003b蓝屏
- 如何快速剪辑多个视频,将视频分段保存导出播放
- 头文件 INTRINS.H 的用法
- 【译】AN1297:使用Silicon Labs蓝牙协议栈的定制测向解决方案
- 物联网卡智能净水器打造智慧洁净生活