python单元测试mock,单元测试mock静态方法
1.有什么问题?
单元测试的目标是一次只验证一个方法,用小步骤和细粒度的测试。但是如果某个方法依赖于其他难以控制的东西,比如网络连接、数据库连接或者Servlet容器,怎么办?
如果您的测试依赖于系统的其他部分,或者甚至系统的许多其他部分,该怎么办?在这种情况下,如果
如果您不小心,您可能最终会发现自己几乎初始化了系统的每个组件,只是为了给一个测试创建足够的运行环境,以便它们可以运行。忙了半天,看起来挺好的。
似乎有点违背测试的初衷。这不仅耗费时间,还会在测试过程中引入很多耦合因素。举个例子,有人可能兴致勃勃地更改数据库中的一个界面或一个表,突然,你那不起眼的单元测试神秘地挂掉了。这种情况发生几次后,即使是最有耐心的开发人员也会望而却步,最后甚至放弃所有的测试。那样的话,后果可想而知。
我们来看一个更具体的情况:在实际的面向对象软件设计中,我们经常会遇到这种情况。
事实上,在我们构建真实对象之后,对象是通过一系列接口来实现的。这是面向对象设计中最自然的事情,但是随着软件测试需求的发展,它会
有一些小问题。举个例子,现在用户A得到了用户B提供的一个接口,他根据这个接口实现了自己的需求,但是用户A编译了自己的代码之后,想要简单的模拟测试一下。怎么会?
我该怎么办?这也是一个很现实的问题。我们能简单地为这个接口实现一个代理类来测试模拟并期望代码生成自己的结果吗?
幸运的是,有一个测试模式可以帮助我们:模拟对象。在调试过程中,模拟对象是真实对象的替代品。
2.现在需要模拟对象吗?
Tim Mackinnon就何时需要模拟对象给了我们一些建议:
-真实对象具有不确定的行为(产生不可预测的结果,如股票市场)
-真实对象很难创建(如混凝土web容器)。
-真实对象的一些行为很难触发(比如网络错误)
-真实情况使得程序运行非常缓慢。
-真实物体有用户界面。
-测试需要询问真实对象它是如何被调用的(例如,测试可能需要验证回调函数是否被调用)
-真实对象实际上并不存在(这是与其他开发团队或新硬件系统打交道时的常见问题)
3.如何实现模拟对象?
当使用模拟对象进行测试时,我们总共需要三个步骤,即:
-使用一个接口来描述这个对象。
-为产品代码实现此接口。
-出于测试目的,该接口在模拟对象中实现。
在这里,我们再次看到了接口编程的重要性,因为被测试的代码只能通过接口引用。
对象,所以它不知道自己引用的是真实对象还是模拟对象。我们来看一个实际的例子:一个闹钟根据时间作为提醒,下午5点以后播放。
播放音频文件,提醒大家下班了。如果要用实物测试,只能等到下午五点,然后把耳朵放在音箱旁边.我们不想这么蠢,应该利用他们。
模拟对象来测试,这样我们就可以模拟控件时间,而不是等时钟转到下午5点。代码如下:
公共接口环境{
private boolean playedWav=false
public long getTime();
public void playWavFile(字符串文件名);
public布尔值wavWasPlayed();
public void reset wav();
}
公共类系统环境实现环境{
public long getTime() {
返回system . current time millis();
}
public void playWavFile(字符串文件名){
playedWav=true
}
public boolean wavWasPlayed() {
返回playedWav
}
public void resetWav() {
playedWav=false
}
}
公共类模拟系统环境实现环境{
私有长电流时间
public long getTime() {
返回当前时间;
}
公共void setTime(长当前时间){
这个。当前时间=当前时间;
}
公共void playWavFile(字符串文件名){
playedWav=true
}
public boolean wavWasPlayed() {
返回playedWav
}
public void resetWav() {
playedWav=false
}
}下面是一个调用取得时间的具体类:
导入Java。util。日历;
公共类检查器{
私人环境包封/包围(动词envelop的简写)
公共检查员(环境){
this.env=env
}
公共作废提醒(){
日历cal=日历。getinstance();
加州settimeinmills(env。gettime());
int hour=cal.get(日历。一天中的小时);
如果(小时=17) {
环境。playwavfile(‘退出_口哨。wav’);
}
}
}
使用env.getTime()的被测代码并不知道测试环境和真实环境之间的区别,因为它们都实现了相同的接口。现在,你可以借助模拟的对象,通过把时间设置为已知值,并检查行为是否如预期那样来编写测试。
导入Java。util。日历;
导入朱尼特。框架。测试用例;
公共类测试检查器扩展测试案例{
public void testQuittingTime() {
MockSystemEnvironment env=new MockSystemEnvironment();
日历cal=日历。getinstance();
校准设置(日历。年,2006年);
校准设置(日历。月,11日);
校准设置(日历。月日,7);
校准设置(日历。一天中的小时,16);
校准设置(日历。分钟,55);
长t1=cal。gettimeinmillis();
环境。settime(t1);
Checker Checker=new Checker(env);
检查者。提醒();
断言false(env。wavwasplayed());
t1=(5 * 60 * 1000);
环境。settime(t1);
检查者。提醒();
断言true(env。wavwasplayed());
环境。reset wav();
t1=2 * 60 * 60 * 1000
环境。settime(t1);
检查者。提醒();
断言true(env。wavwasplayed());
}
}
这就是模拟的对象的全部:伪装出真实世界的某些行为,使你可以集中精力测试好自己的代码。
4.好像有一些麻烦
如果每次都像上面那样自己写具体的模拟的对象,问题虽然解决了,但是好像有一些麻
烦,不要着急,已经有一些第三方现成的模拟的对象供我们使用了。使用模拟的
目标进行测试,主要是用来模拟那些在应用中不容易构造(如对象必须在小型应用程序容器中才能构造出来)或者比
较复杂的对象(如数据库编程中的结果集对象)从而使测试顺利进行的工具。目前,在爪哇阵营中主要的模拟的测试工具有
JMock,MockCreator,Mockrunner,EasyMock,MockMaker等,在微软的。网阵营中主要是
Nmock,1000 .NetMock等。
下面就以利用静态导入模拟测试小型应用程序组件为例,代码如下:
编译并将其当做一个试验
情况运行,会发现两个测试方法均测试成功。我们可以看到easymock已经帮助我们实现了一些小型应用程序组件的模拟的对象,这样我们就可以摆
脱网容器和小型应用程序容器来轻松的测试小型应用程序了。
导入org。easymock。*;
导入朱尼特。框架。*;
导入javax。servlet。http。*;
公共类MockRequestTest扩展了测试用例{
私有模拟控制控件;
私有HttpServletRequest模拟请求
public void testMockRequest(){
//创建一个模拟对象的模拟控制对象
控制=模拟控制。创建控件(http servlet请求。类);
//获取一个模拟对象对象
模拟请求=(http servlet请求)控制。get mock();
//设置期望调用的模拟对象对象的方法
模拟请求。getparameter( name );
//设置调用方法期望的返回值,并指定调用次数
//以下后两个参数表示最少调用一次,最多调用一次
control.setReturnValue(kongxx ,1,1);
//设置模拟对象的状态,
//表示此模拟对象对象可以被使用
控制。重播();
//使用断言检查调用
assertEquals(kongxx ,模拟请求。getparameter( name );
//验证期望的调用
控制。verify();
}
}
编译并作为测试用例运行,你会发现两种测试方法都测试成功。我们可以看到easymock已经帮助我们实现了一些servlet组件的mock对象,这样我们就可以摆脱web容器和servlet容器来轻松测试servlet了。
5.底层技术是什么?
我们回想一下,如果用户使用C和java生成程序,C处于最后阶段。
还需要连接生成一个完整的程序,在灵活性上是java源代码的机制无法比拟的。java的每个类都是独立的,打包的类也是独立的,所以只能加载进去。
行,这在代码加载的时候,我们还可以执行很多动作,比如插入一些相关的业务需求,这也是AOP的一个重点。javassit代码库的实现类似于
这就是这些的用途,所以用java实现Mock对象非常简单。
6.一些相关资源
http://www.mockobjects.com/, Mock Object主页,介绍了关键Mock Object的基本概念和目前各种环境下的主要Mock测试工具。
http://www.jmock.org/, JMock的主页,可以获得JMock的最新代码和开发工具包,以及一些说明文档。
EasyMock的主页,http://www.easymock.org/,可以获得JMock的最新代码和开发工具包,以及一些说明文档。
NMock的主页http://www.nMock.org/,介绍了微软的模拟测试开发工具。Net平台。
转自:http://tech.ccidnet.com/art/3539/20070809/1172211_1.html
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。