Jmockit 的使用简单介绍

来源:互联网 发布:不服淘宝小二判决 编辑:程序博客网 时间:2024/06/08 06:28


最近项目需要测试,就用到了jmockit,具体可以访问:http://jmockit.org/about.html

.Mock的使用场景:

比如以下场景:

1. mock掉外部依赖的应用的HSF service的调用,比如uic,tp 的hsf服务依赖。

2. 对DAO层(访问mysql、oracle、tair、tfs等底层存储)的调用mock等。

3. 对系统间异步交互notify消息的mock。

4. 对method_A里面调用到的method_B 的mock 。

5. 对一些应用里面自己的 class(abstract, final, static),interface,annotation ,enum,native等的mock。

JMockit 是用以帮助开发人员编写测试程序的一组工具和API,它(https://code.google.com/p/jmockit/)完全基于 Java5 SE 的 java.lang.instrument 包开发,内部使用 ASM 库来修改Java的Bytecode。正是由于基于instrument,可以修改字节码。所以这也是它强大的原因。

    Jmockit可以mock的种类包含了:

        1.class(abstract,final, static)

        2.interface

        3.enum

        4.annotation

        5.native

 

        Jmockit有两种mock的方式:

        1. Behavior-oriented(Expectations& Verifications)  ; 

       2. State-oriented(MockUp<GenericType>) 

通俗点讲,Behavior-oriented是基于行为的mock,对mock目标代码的行为进行模仿,更像黑盒测试。State-oriented 是基于状态的mock,是站在目标测试代码内部的。可以对传入的参数进行检查、匹配,才返回某些结果,类似白盒。而State-oriented的 new MockUp基本上可以mock任何代码或逻辑。非常强大。



基于maven构建的项目,在pom.xml中加依赖

<dependency>  

  <groupId>org.jmockit</groupId> 

  <artifactId>jmockit</artifactId> 

  <version>1.20</version>  

  <scope>test</scope>

</dependency>

Jmockit是对Jmock的扩展,它使用起来更方便和强大,上一小段测试代码

public class RunActivityManagerImplTest{
@Tested
RunActivityManagerImpl runActivityManagerImpl = new RunActivityManagerImpl();
@Injectable
UserRunActivityAwardDao userRunActivityAwardDao;

@Test
public void testPlayFlowGame() {
new NonStrictExpectations() {
{
userRunActivityAwardDao.selectGameChance(anyInt,
DateUtils.getStringDateShort());
returns(0, 0);
userRunActivityAwardDao.countUserlottery(2, anyInt,
DateUtils.getStringDateShort());
returns(10, 0);
userRunActivityAwardDao.insert(new UserRunActivityAward(anyInt,
2, anyInt));
userRunActivityAwardDao.selectlottery(anyInt, anyInt,
anyString, anyInt, anyInt);
returns(1, 0, 200);
}
};
runActivityManagerImpl.playFlowGame(1, 0);
new MockUp<Activity>() {
@Mock
boolean getHasGiveOut() {
return false;
}
};
java.util.Map<String, Object>map =runActivityManagerImpl.playFlowGame(1, 1);

          if(map != null) {
boolean result = (int) map.get(CloudHealthUtils.MOBILE_RECODE) >= 0;
Assert.assertTrue(result);
} else {
Assert.assertNull(map);
}

}

}

此段代码调用了两次测试runActivityManagerImpl.playFlowGame(1,0),runActivityManagerImpl.playFlowGame(1, 1);

returns(result1,result2,...),代表Mock对象方法被调用几次,以及每次返回的结果,调用次数可以用times=n(次数),来指定。当然不指定也是可以的,当调用此时大于返回的结果集个数,则就以最后一个result,作为超过调用次数的结果。

当然我这里用的newNonStrictExpectations() 是不严格的,也可以用new Expectations() 。测试一个方法一般分为三步

            1. record阶段:录制期望。也可以理解为数据准备阶段。创建依赖的class或interface或method,模拟返回的数据,及调用的次数等

             2. replay阶段:通过调用被测代码,执行测试。期间会invoke到 第一阶段record的mock对象或方法。

3. verify阶段:验证。可以验证调用返回是否正确。及mock的方法调用次数,顺序等。

 


0 0