unit test pattern--1
来源:互联网 发布:拉拉肥捏脸数据 编辑:程序博客网 时间:2024/05/16 19:33
首先要说一下哪部分code一定要有unit test.
1. 依赖第三方接口的模块。因为第三方提供的结果不一定完全可信,数据可能会变化。如果有针对第三方接口的测试,当程序出现问题时,我们跑一下unit test, 就可以先判断出是第三方接口数据有变化还是自己的代码有问题。这样可以缩短debug的时间。
2. 模块之间的接口。和上面的原因一下,模块之间的接口是连接几个模块的唯一通道。通过对接口测试,也可以先把问题缩写在某个模块。
下面说一下可能在单元测试中需要注意的地方。
1. 子单元测试
想一想你有没有遇到过以下的问题。你的单元测试失败了,但是你要花费一段时间才能定位到错误的原因。为什么会这样,是因为unit test负责的功能太大了。这个时候需要把这一个unit test分成几个小的test进行测试。
我也会遇到这个问题。一个类它提供了public的接口。我会写unit test测试这个接口。但是这个接口可能是有三个函数实现的,比如A,B,C。所以当我发现unit test失败时,我不知道是A,B,C哪个错误导致的。那现在如果我们分别针对A,B,C也加了unit test进行测试,这样我们就会更容易地定位出错的地方。那如果在这里A可能是private的话,那A需要unit test为这个函数测试吗?
针对private(或protected)的函数是否需要测试的问题,有人说不应该对private 函数测试,因为private 函数之所以设置成private就是不想让外界访问,而且private 的函数可能更容易变化,这样导致unit test也要跟着变。也有人说如果需要可以对private 函数测试,就是因为如果不针对子函数进行测试的话,可能导致错误不容易定位的问题。对我来说,在某些情况下,还是会有对private函数进行测试的时候。
针对private,可以通过反射机制访问。针对protected的函数,我一般会让unit test的class继承被测试的类,这样在unit test的class中就可以访问到要测试的函数了。
2. Mock Object
我想写过unit test的人,几乎都写过Mock Object. Mock是模仿的意思,证明不是真正的对象。比如你要测试依赖数据库的逻辑是否正确,但是你真正去操作一个数据库,可能会对数据库的记录造成影响。或者你现在对一个文件进行操作,对文件进行操作你需要处理IO异常的情况。但是如果你读取的是一个真正的文件,你可能永远不知道处理IO异常的代码是否正确。这个时候你就可以用一个Mock的对象去模拟IO出现异常,看看你的程序是否能正常处理这个情况。
比如你定义一个class,它继承自StreamWriter(通过streamwriter访问文件).
class MockStreamWriter : StreamWriter { public override void Write(string value) { throw new IOException(""); } }
在unit test测试时,将需要StreamWriter的时候,传入MockStreamWriter的对象,这样当调用Write方法时,就调用了MockStreamWriter的Write方法,这个时候你就可以测试你的代码能否成功handle IOException.
3. Self Shunt
Self Shunt就是说我们可以把unit test自己作为Mock Object, 而不需要额外再创建一个class. 比如现在有一个class Person, 这个class有很多Listener, 只要Person中的Notify执行,就会把object的状态通知Listener.
class Person { //other methods and fields.... public IList<Listener> ListenerList; public void Notify() { for (int i=0; i<ListernList.count; i++) { ListenerList[i].Accept(this); } } }
正常测试时,我们需要Mock Listener, 它继承自Listener.
class MockListener : Listener{ public int Count = 0; public override void Accept(Person p) { Count++; }}
Unit Test:
public void Test(){ Person p = new Person(); MockListener listener = new MockListener(); p.ListenerList.Add(listener). p.Notify(); Assert.AreEqual(1, listener.Count);}
现在我们让Unit Test的class再增加一个功能,即作为MockListener.
class MockListener_UnitTest : Listener{ public int Count = 0; public override void Accept(Person p) { Count++; } public void Test() { Person p = new Person(); p.ListenerList.Add(this). p.Notify(); Assert.AreEqual(1, this.Count); }}
这样做的好处是你可以不用再写一个额外的class了。但是有可能你需要实现Listener所有的接口(可以返回一个合理的值或者抛出异常)。把Unit Test本身作为Mock object, 代码读起来更方便。
- unit test pattern--1
- unit test
- Unit Test
- Unit test
- UNIT TEST
- Unit Test
- Unit Test
- Unit Test、 UI Test
- 如何写Unit Test, TDD 入门1
- Android Testing Fundamentals 1, unit test
- unit Test 筆記-write unit test
- [转]Unit Test 原则
- Unit Test研究报告
- vs2005 unit test 点滴
- Design to Unit Test
- Unit Test Frameworks
- j2me unit test
- Unit Test Key Points
- [LeetCode 143]Reorder List
- Applications using Launch Screen Files and targetting iOS 7.1 报错
- 关于PPT模板的制作
- 并发请求导致的业务处理安全风险及解决方案
- 黑马程序员-----浅谈面向对象的含义
- unit test pattern--1
- Python-memcached的基本使用
- jar命令行的详解
- 黑马程序员—C学习笔记—指针字符串与其内存细节
- 数字类型转换问题
- jquery滚动加载数据
- 分离颜色通道&多通道图像融合
- SpringMVC @ResponseBody
- Android应用中埋点监控的思考与设计