看看下面的图:
|-----------------------------------------------------------------|
| |
| |---------------------| | |-----------------------------|
| | Tested | <------------------------------------------à | External Mock Object |
| | Object | | |----------------------------|
| |---------------------| |
| /|\ |--------------------| |
| |-------〉 | Internal Mock | |
| | Object | |
| |--------------------| |
| [Your system scope] |
|--------------------------------------------------------- --------|
在测试你的Tested Object时,你可能会与你系统内的某个模块或系统外某个实体交互,而这些模块或实体在你做单元测试的时候可能并不存在,这时:
Ø Internal Mock Object可能是一个你的系统尚未完成的模块的“替身”(replacement);
Ø External Mock Object可能是测试你的Tested Object时需要的外部的环境实体的“替身”(replacement)。
不知道这样给Mock Object分类是否正确J
我们来看看与Real world object交互有什么不足之处:
Ø Real world object的行为具有不确定性,我们难于控制它们的输出or返回结果。
Ø Real world object有些时候是难于被建立的或者说是无法获得的。
Ø Real world object的有些行为难于被触发,如磁盘已满,网络error等。
Ø Real world object可能不存在,比如你的Tested Object需要与你的系统的另一个module交互,而另一个module尚未开发完毕。
当然还不止这些,我们仅仅是列出一部分。
使用Mock Object替代Real world object后我们就会解决上述问题,换句话说当上面的情况出现后,我们就可以使用Mock Object。这也是什么时候该使用Mock Object的answer。
Mock Object是我们自己编写的,我们拥有控制它的绝对的权力,我们可以定制它的行为和输出。
Use Mock Object
使用Mock Object解决上述问题可分三步走:
1. Use an interface to describe the object
2. Implement the interface for production code
3. Implement the interface in a mock object for testing [3]
还有一点就是对于Internal Mock Object早晚你要实现出其Real world object的,因为那是你系统的一部分。
一个改自资料[3]的例子
public interface Environmental {
public long getTime();
// Other methods omitted...
}
对于这样一个接口,我们提供两种实现,
//real world object
public class SystemEnvironment implements Environmental {
public long getTime() {
return System.currentTimeMillis();
}
// other methods ...
}
//mock object
public class MockSystemEnvironment implements Environmental {
public long getTime() {
return currentTime;
}
public void setTime(Time aTime){
this.currentTime = aTime;
}
private Time currentTime;
//others
}
我们可以看到在MockSystemEnvironment中我们提供“setTime”函数是为了提供控制Mock Object的接口。
我们要测试的类
//TestedObject
public class TestedObject{
private Environmental env;
TestedObject(Environmental aEnv){
this.env = aEnv;
}
public boolean isAm(){
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(env.getTime());
int hour = cal.get(Calendar.HOUR_OF_DAY);
if (hour <=12) return true;
return false;
}
}
将要测试的类放入单元测试框架
public class TestTestedObject extends TestCase {
public void testIsAm(){
MockSystemEnvironment env = new MockSystemEnvironment();
// Set up a target test time
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2004);
cal.set(Calendar.MONTH, 10);
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.HOUR_OF_DAY, 16);
cal.set(Calendar.MINUTE, 55);
long t1 = cal.getTimeInMillis();
env.setTime(t1);
TestedObject to = new TestedObject(env);
assertFalse(to.isAm());
}
}
在该单元测试中我们使用了Mock Object,并且在使用前我们利用setTime接口,输入了我们需要的值。结果我们会通过测试。如果我们使用Real Object,我们得到的测试结果将是不固定的,后者可不是所期望的。从这个例子中你也应该体会到Mock object的一些好处了。
如果我们总是手动写我们需要的Mock Object,那将是一个很大的工作量。现在业界有了Mock Objects、easy mock等开源框架的支持,是我们编写Mock object变得越来越容易。
参考资料:
1、《Test-Driven Development ? A practical guide》
2、《JUnit in action》
3、《Pragmatic Unit Testing》
相关推荐
不错的文档,提供给科研人员
MockObject类具有两个主要功能: * 它维护一个函数返回值的查找表:对于任何函数,对于特定函数,或者对于具有特定参数的特定函数*它维护了调用方法的列表以及使用的参数。 例子 有关如何工作的示例,请参阅示例子...
Python单元测试库,A mock object is created to represent a real object for the purposes of a unit test. Using a mock object rather than the real object can be useful if the real object is difficult to ...
MockServer 是一个强大的工具,主要用于在开发过程中模拟服务器行为,特别是在接口开发和测试阶段。它允许开发者在没有实际后端服务的情况下,创建模拟的HTTP和HTTPS服务器,以便于快速验证前端代码或者自动化测试。...
Mock技术在软件开发中扮演着重要的角色,尤其是在测试领域。它允许开发者在不依赖实际环境或第三方服务的情况下,创建模拟对象来代替真实组件,以便进行单元测试和集成测试。这样可以提高测试效率,减少测试复杂性,...
Python 提供了一个强大的库——`unittest.mock`,用于模拟(mock)对象、方法和类,以便在测试中隔离依赖关系,专注于测试目标代码的功能。本练习主要关注如何使用 `unittest.mock` 进行mock测试数据。 一、Mock...
官方离线安装包,测试可用。请使用rpm -ivh [rpm完整包名] 进行安装
Mock是一个强大的服务端模拟工具,它的核心特性是零侵入性,这意味着在你的实际项目代码中无需进行任何修改,即可实现服务的模拟。这极大地提高了开发效率,特别是在进行集成测试或者依赖于其他服务但又无法实时访问...
Classes contained in spring-mock.jar: org.springframework.mock.jndi.ExpectedLookupTemplate.class org.springframework.mock.jndi.SimpleNamingContext.class org.springframework.mock.jndi....
在C++中,你可以使用`NiceMock`、`StrictMock`和`MockObject`来创建不同类型的模拟对象。`NiceMock`默认对未指定的调用采取宽容态度,而`StrictMock`则要求所有调用都必须预先设置。`MockObject`允许自定义行为。 ...
Mock技术在软件开发中扮演着重要的角色,尤其是在测试阶段。它允许开发者在真实环境尚未准备好或不可用时,创建模拟对象来替代实际依赖,以便进行功能验证和性能测试。本项目涉及的内容是关于如何在Windows或Linux...
标题中的"Mock Object Generator for VBMock-开源"明确指出这是一个专为VBMock设计的Mock对象生成器,并且是开放源代码的。这意味着任何开发者都可以查看其内部实现,根据自己的需求进行定制,甚至贡献代码改进项目...
在IT行业中,Mock技术是一种非常重要的测试方法,特别是在前端开发中。它允许开发者在不依赖实际后端服务的情况下,对应用程序进行单元测试和集成测试。`模拟mock.zip`这个压缩包文件显然与Mock技术相关,其中包含的...
在Linux系统管理中,`Mock`是一个非常有用的工具,尤其对于开发者和打包人员而言,它能够在隔离环境中构建RPM软件包。在CentOS 7环境下,`Mock`可以帮助我们在不干扰系统其他组件的情况下测试和构建RPM包。下面将...
Mock.js 数据模拟技术 Mock.js 是一种流行的前端数据模拟技术,用于模拟后端接口的响应数据,使得前端开发可以独立于后端开发,提高开发效率和体验。本文将从 Mock.js 的安装、使用、方法、注意事项等方面进行总结...
设置完成后,可以通过`Object`属性访问Mock对象并调用其方法来进行测试。 ```csharp // 调用AddCall方法 customer.Object.AddCall(); // 断言GetCall方法的返回值 Assert.AreEqual("phone:89898789", ...
mock
在软件开发中,尤其是在测试阶段,MockServer可以替代真实的后端服务,允许开发者在没有实际依赖的情况下进行单元测试和集成测试。这个“mockserver1.zip”文件包含了启动和使用MockServer所需的一些基本组件和配置...