假冒的艺术
预处理的接入点
上面第二点通常要求提供同名的头文件,而使用不同的构建设置 而第三点不要求同名,只要使用相同的防卫宏,并保证把包含替代声明的头文件放在真正的头文件前面包含进来就可以,使用同一构建设置即可 编译链接的接入点
运行时的接入点
基本上两个原则
例子: 测试使用了 static 函数,new 操作符的客户代码在 TDD 流行之后,关于 Singleton,static 函数,new 操作符等依赖具体实现的代码被推荐避免使用. 遗留系统中则不可避免的保留着. 它们被批评的原因是使它们的客户代码难以测试. 我们可以利用 "使用函数封装数据访问,可以子类化以接入假的实现" 来进行测试. public class SingletonClient { public void doSomething(){ SingletonObject service = SingletonObject.instance(); service.execute(); } } 上面的这个SingletonClient的doSomething是无法测试的,因为引用了一个静态函数. 可以把对静态函数的引用抽取到一个可覆写的函数中来引入接入点: class SingletonClient { public void doSomething(){ SingletonObject service = getServiceObject(); service.execute(); } protected SingletonObject getServiceObject() { return SingletonObject.instance(); } } 这样测试时我们便可以子类化SingletonClient,只重写getServiceObject,便可以针对这个子类进行测试,效果与针对基类测试是一样的(因为其它的函数实现都相同,只是依赖的第三方对象被替换为了假的实现): class SingletonClientInTestEnvironment extends SingletonClient { protected SingletonObject getServiceObject() { return new SingletonObjectStub(); } } 例子: C++ 测试,用遮盖技术(定义同名服务类),当同时需要测真正的服务类本身时如何解决链接问题? (重定义)那就不要定义同名的类,#define 一个宏加一层间接,恰当的时候 #undef. 如果是函数,可以定义一个函数对象来封装想假冒的函数,生成该函数对象类型的一个变量时,使用与函数相同的名字,利用名字的作用域规则来遮盖原来的函数. (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |