jmockit教程_jmockit使用总结-MockUp重点介绍
公司对开发人员的单元测试要求比较高,要求分支覆盖率、行覆盖率等要达到60%以上等等。项目中已经集成了jmockit这个功能强大的mock框架,学会使用这个框架势在必行。从第一次写一点不会,到完全可以应付工作要求,期间踩了好多坑,学到了不少东西。下面简单总结一下jmockit这个框架的使用,重点介绍MockUp的使用,因为项目中都采用此种方式模拟方法。
一、框架集成
添加maven依赖
org.jmockit
jmockit
1.16
test
junit
junit
4.12
二、@Mocked模拟方式介绍
@Mocked模拟,由录制、回放、验证三步骤完成,是对某个类的所有实例的所有方法进行完整的模拟方式。
/*** 被测试类*/
public classApp {publicString say() {return "Hello World";
}publicString say2(){return "Hello World 2";
}public staticString staticSay() {return "Still hello world";
}
}
/*** 测试类*/
public classAppTest {/*** 针对类及所有实例的的整体模拟,未写录制的方法默认返回0,null等*/@Mocked
App app;
@Testpublic voidtestSay() {//录制,定义被模拟的方法的返回值,可以录制多个行为,写在一个大括号里也可以,多个大括号隔开也可以
newExpectations() {{
app.say();
result= "say";
}};//回放,调用模拟的方法
System.out.println(app.say()); //say
System.out.println(new App().say()); //say
System.out.println(App.staticSay()); //null//验证
newVerifications() {{//验证say模拟方法被调用,且调用了2次
app.say();
times= 2;//验证staticSay模拟方法被调用,且调用了1次
App.staticSay();
times= 1;
}};
}
}
三、@Injectable模拟方式介绍
@Injectable和@Mocked的方式很像,区别是@Injectable仅仅对当前实例进行模拟。
/*** 测试类*/
public classAppTest001 {/*** 仅针对当前实例的整体模拟*/@Injectable
App app;
@Testpublic voidtestSay() {//录制
newExpectations() {{
app.say();
result= "say";
}};//回放
System.out.println(app.say()); //say,模拟值
System.out.println(app.say2()); //null,模拟默认值
final App appNew = newApp();
System.out.println(appNew.say());//Hello World,未被模拟,方法实际值
System.out.println(App.staticSay()); //Still hello world,未被模拟,方法实际值//验证
newVerifications() {
{//验证say模拟方法被调用
app.say();
times= 1;
}
{
appNew.say();
times= 1;
}
{//验证staticSay模拟方法被调用,且调用了1次
App.staticSay();
times= 1;
}
};
}
}
四、Expectations传参,局部模拟
/*** 测试类*/
public classAppTest002 {
@Testpublic voidtestSay() {final App app = newApp();//录制,带参数表示局部模拟【针对所有实例的局部模拟,具体到某个方法的模拟,其它方法不模拟】
new Expectations(App.class) {{
app.say();
result= "say";
}};//回放
System.out.println(app.say()); //say,模拟值
System.out.println(app.say2()); //Hello World 2 ,未被模拟,方法实际值
System.out.println(new App().say()); //say,模拟值
System.out.println(App.staticSay()); //Still hello world,未被模拟,方法实际值
}
}
五、MockUp局部模拟,可重写原有方法的逻辑,比较灵活,推荐使用
/*** 测试类*/
public classAppTest003 {
@Testpublic voidtestSay() {//局部模拟【针对所有实例的局部模拟,具体到某个方法的模拟,其它方法不模拟】
new MockUp(App.class){
@Mock
String say(){return "say";
}
};//回放
System.out.println(new App().say()); //say,模拟值
System.out.println(new App().say2()); //Hello World 2,未被模拟,方法实际值
System.out.println(App.staticSay()); //Still hello world,未被模拟,方法实际值
}
}
六、MockUp如何模拟私有方法、静态方法、静态块、构造函数等
1.模拟私有属性(实例属性和类属性),MockUp不支持,采用如下方式
//模拟实例的字段
Deencapsulation.setField(Object objectWithField, String fieldName, Object fieldValue)//模拟类的静态字段
Deencapsulation.setField(Class> classWithStaticField, String fieldName, Object fieldValue)
2.模拟私有方法,MockUp不支持,采用如下方式
//模拟实例方法,注意参数不能为null,如果要传null请使用带参数类型的另一个重载方法
Deencapsulation.invoke(Object objectWithMethod, String methodName, Object... nonNullArgs)//模拟类方法
Deencapsulation.invoke(Class> classWithStaticMethod, String methodName, Object... nonNullArgs)
3.模拟静态方法
和模拟实例方法一样,去掉static即可
4.模拟静态块
//mock静态代码块
@Mockvoid$clinit(Invocation invocation){
}
5.模拟实例块和构造函数
//mock代码块和构造函数
@Mockvoid$init(Invocation invocation) {
}
6.模拟接口,MockUp不支持,采用@Capturing
/*** 被模拟的接口*/
public interfaceIUserService {
String getUserName( );
}
public class UserServiceImpl implementsIUserService {
@OverridepublicString getUserName() {return "Bob";
}
}
/*** 接口模拟测试*/
public classIUserServiceTest {/*** MockUp不能mock接口方法,可以用来生成接口实例*/@Testpublic voidgetUserNameTest001(){
MockUp mockUp = new MockUp(){
@Mock
String getUserName( ){return "Jack";
}
};
IUserService obj= newUserServiceImpl();
System.out.println(obj.getUserName());//Bob,mock失败
obj=mockUp.getMockInstance();
System.out.println(obj.getUserName());//Jack,mockUp生成的实例,和自己写一个接口实现一样
obj= newUserServiceImpl();
System.out.println(obj.getUserName());//Bob,mock失败
}/*** @Capturing 注解可以实现mock接口,所有实现类的实例均被mock
*@parambase*/@Testpublic void getUserNameTest002(@Capturing finalIUserService base){
IUserService obj= newUserServiceImpl();
System.out.println(obj.getUserName());//mock成功,返回模拟默认值null//录制
newExpectations(){
{
base.getUserName();
result= "Jack";
}
};
System.out.println(obj.getUserName());//Jack
obj= newIUserService() {
@OverridepublicString getUserName() {return "Alice";
}
};
System.out.println(obj.getUserName());//Jack
}
}
七、MockUp模拟方法中调用原方法
/*** 模拟方法调用原方法逻辑测试*/
public classJSONObjectTest {
@Testpublic voidgetTest(){
JSONObject jsonObject= newJSONObject();
jsonObject.put("a","A");
jsonObject.put("b","B");
jsonObject.put("c","C");
System.out.println(jsonObject.get("a")); //A
System.out.println(jsonObject.get("b")); //B
System.out.println(jsonObject.get("c")); //C
new MockUp(){
@Mock
Object get(Invocation invocation,Object key){if("a".equals(key)){return "aa";
}else{//调用原逻辑
returninvocation.proceed(key);
}
}
};
System.out.println(jsonObject.get("a")); //aa
System.out.println(jsonObject.get("b")); //B
System.out.println(jsonObject.get("c")); //C
}
}
八、MockUp单元测试用例单个跑正常,批量跑失败可能的原因
1.测试方法使用了共享变量,相互影响。
2.在一个测试方法里多次MockUp同一个类,将某个类需要mock的方法均写在一个new MockUp里即可解决,原因未知。
3.在测试方法里的MockUp,在方法结束前,调用一下mockUp.tearDown。
jmockit教程_jmockit使用总结-MockUp重点介绍相关推荐
- jmockit教程_JMockit常用操作
JMockit常用操作 目录 1 基本概念 1.1 常用注解 @Mocked:被修饰的对象将会被Mock,对应的类和实例都会受影响(同一个测试用例中) @Injectable:仅Mock被修饰的对象 ...
- jmockit教程_Jmockit(一): 入门
1 pom配置 testng + jmockit,使用junit也可以 org.testng testng 6.14.3 test org.jmockit jmockit 1.41 test 2 程序 ...
- jmockit教程_Jmockit教程(各种整理的心得)
Paste_Image.png 在JMockit库, Expectations(期望)API提供了使用自动化的开发人员测试mock的丰富的支持. 当mock使用,在测试的重点是代码的被测行为,如通过其 ...
- jmockit教程_jmockit demo
1.@Mocked,标识一个指定的class的实例或被测对象的参数被Mock掉. 2.@Capturing,标识一个被Mock的对象,从该对象派生的子类也被Mock了. 3.@Injectable,标 ...
- Midjourney|文心一格prompt教程[基础篇]:注册使用教程、风格设置、参数介绍、隐私模式等
Midjourney|文心一格prompt教程[基础篇]:注册使用教程.风格设置.参数介绍.隐私模式等 开头讲一下为什么选择Midjourney和文心一格,首先Midjourney功能效果好不多阐述: ...
- 会议重点介绍芯片设计中的人工智能
会议重点介绍芯片设计中的人工智能 Conference highlights AI in chip design, IoT 旧金山-谷歌正在试验机器学习(ML)来执行IC设计中的地点和路线,并取得了很 ...
- 【建站系列教程】3.1、cookie介绍
[建站系列教程]3.1.cookie介绍 cookie的应用场景 1 小说网站的字体.颜色.背景颜色设置 2 隐藏url里面的参数 cookie的通俗介绍 cookie的基本用法 js版本 jQuer ...
- Arduino可穿戴开发入门教程LilyPad和LilyPad Simple的介绍
Arduino可穿戴开发入门教程LilyPad和LilyPad Simple的介绍 LilyPad和LilyPad Simple的介绍 LilyPad和LilyPad Simple是LilyPad微控 ...
- Quartz教程三:Job与JobDetail介绍
Quartz教程三:Job与JobDetail介绍 原文链接 | 译文链接 | 翻译:nkcoder | 校对: 本系列教程由quartz-2.2.x官方文档翻译.整理而来,希望给同样对quartz感 ...
最新文章
- 《编写高质量代码:改善c程序代码的125个建议》——建议3-5:避免使用浮点数作为循环计数器...
- 关于adb devices连不上手机的几种情况
- [development][PCRE] old PCRE
- 提高阅读源代码的效率 转
- 使用 HTTP 缓存防止不必要的网络请求
- effective C++ 条款 3:尽可能使用const
- Teams团队的成员列表API的已知问题
- 日常spoken英语学习
- can't request region for resource [mem 0xfed40080-0xfed40fff]问题的解决办法
- input readonly 光标显示问题
- Firefox下强制页面缓存失效的设置方法
- crfpp python
- Redis教程:数据对象分析(二)
- 网站SEO优化--Flash站优化方法
- php爬取网站所有链接,php 爬取超链接
- 【SVPWM】SVPWM算法推导及其Simulink仿真(二)
- win8.1虚拟机装linux,Linux VirtualBox安装Win8.1报错0x000000C4怎么办?
- 【Testin实验室】MoiMark安卓中国终端体验性能排行榜(11月报)
- Unity 最新UnityWebRequest下载,同时显示下载进度,和 显示网速,今天贴出来和大家分享
- 模拟信号隔离器|隔离放大器|隔离变送器 常见问题解答