Mock、Powermock使用汇总
程序员文章站
2022-11-07 12:02:54
mock、powermock使用学习,mock静态方法、私有方法。 ......
背景
工作中经常用到单测,某对单测掌握的不好,所以趁此学习、总结一下。
主要参考:https://www.jianshu.com/p/0c2480b1709e、https://www.cnblogs.com/ljw-bim/p/9391770.html
一、不依赖外部方法的单测
1、待测试类
package com.shuimutong.demo.junit; /** * 无依赖方法 * @classname: notstaticmethod * @description:(这里用一句话描述这个类的作用) * @author: 水木桶 * @date: 2019年10月26日 上午10:37:09 * @copyright: 2019 [水木桶] all rights reserved. */ public class norelaymethod { public static int add_num = 2; public static int staticaddtwo(int num) { return num + add_num; } /** * 非静态方法 * @param num * @return */ public int notstaticaddtwo(int num) { return num + add_num; } /** * 私有非静态方法 * @param num * @return */ private int privatenotstaticaddtow(int num) { return num + add_num; } }
2、单测类
package com.shuimutong.demo.junit; import java.lang.reflect.method; import org.junit.assert; import org.junit.test; import org.junit.runner.runwith; import org.mockito.injectmocks; import org.powermock.api.mockito.powermockito; import org.powermock.core.classloader.annotations.preparefortest; import org.powermock.modules.junit4.powermockrunner; /** * 参照1:https://www.jianshu.com/p/0c2480b1709e * 参照2:https://www.cnblogs.com/ljw-bim/p/9391770.html * @classname: norelaymethodtest * @description:(这里用一句话描述这个类的作用) * @author: 水木桶 * @date: 2019年10月26日 下午4:14:48 * @copyright: 2019 [水木桶] all rights reserved. */ @runwith(powermockrunner.class) @preparefortest({norelaymethod.class}) public class norelaymethodtest { @injectmocks private norelaymethod norelaymethod; //不需要mock,可以去除上面3个注解 @test public void staticaddtwo() { int num = 3; int result = norelaymethod.staticaddtwo(num); assert.asserttrue(result == (num + norelaymethod.add_num)); } //不需要mock,可以去除上面3个注解 @test public void notstaticaddtwo() { int num = 1; norelaymethod norelaymethod = new norelaymethod(); int result = norelaymethod.notstaticaddtwo(num); assert.asserttrue(result == (num + norelaymethod.add_num)); } //需要mock //mock私有方法 @test public void privatenotstaticaddtow() throws exception { method method = powermockito.method(norelaymethod.class, "privatenotstaticaddtow", int.class); int num = 3; object res = method.invoke(norelaymethod, 3); system.out.println(res); assert.assertequals(num + norelaymethod.add_num, res); } }
3、备注
staticaddtwo和notstaticaddtwo方法不需要runwith、preparefortest、injectmocks这3个注解。
privatenotstaticaddtow涉及到私有方法,需要前面那3个注解。
二、有依赖外部静态方法的单测
1、待测试类
package com.shuimutong.demo.junit; /** * 有依赖其他静态方法 * @classname: relaymethod * @description:(这里用一句话描述这个类的作用) * @author: 水木桶 * @date: 2019年10月26日 下午3:26:01 * @copyright: 2019 [水木桶] all rights reserved. */ public class relaystaticmethod { public final static string default_val = "defaultval"; public final static string signed = "signed"; /** * 依赖静态方法的 * @param key * @return */ public string checkandcalc(string key) { string returnval = null; string savedval = redisutil.get(key); if(savedval == null || savedval.length() < 1) { returnval = default_val; } else { returnval = savedval + "-" + signed; } return returnval; } }
1-1、依赖外部类
package com.shuimutong.demo.junit; import java.util.uuid; public class redisutil { private static boolean init_state = false; public static string get(string key) { if(init_state) { return uuid.randomuuid().tostring(); } else { throw new nullpointerexception("资源未初始化"); } } }
2、单测类
package com.shuimutong.demo.junit; import java.util.uuid; import org.junit.assert; import org.junit.test; import org.junit.runner.runwith; import org.mockito.mockito; import org.powermock.api.mockito.powermockito; import org.powermock.core.classloader.annotations.preparefortest; import org.powermock.modules.junit4.powermockrunner; @runwith(powermockrunner.class) //参考:https://www.jianshu.com/p/0c2480b1709e //1、如果想要对某个类的静态方法进行mock,则必须在preparefortest后面加上相应的类名, 比如此例的redisutil.class。 @preparefortest({redisutil.class}) public class relaystaticmethodtest { /** * mock依赖的静态方法 */ @test public void checkandcalc() { string key1 = "jack"; string key2 = "john"; string val2 = uuid.randomuuid().tostring(); //2、在对该类的某个方法进行mock之前,还必须先对整个类进行mock powermockito.mockstatic(redisutil.class); powermockito.when(redisutil.get(mockito.eq(key1))).thenreturn(null); powermockito.when(redisutil.get(mockito.eq(key2))).thenreturn(val2); relaystaticmethod relaymethod = new relaystaticmethod(); string res = relaymethod.checkandcalc(key1); system.out.println("res:" + res); assert.assertequals(relaystaticmethod.default_val, res); res = relaymethod.checkandcalc(key2); system.out.println("res:" + res); assert.asserttrue(res.contains(relaystaticmethod.signed)); } }
2-1、运行结果
res:defaultval
res:e76dc3b8-fcf5-42b8-9f79-1d308d137514-signed
三、有依赖外部非静态方法的单测
1、待测试类
package com.shuimutong.demo.junit; /** * 参照1:https://www.jianshu.com/p/0c2480b1709e * 参照2:https://www.cnblogs.com/ljw-bim/p/9391770.html * @classname: usercontroller * @description:(这里用一句话描述这个类的作用) * @author: 水木桶 * @date: 2019年10月26日 下午4:14:30 * @copyright: 2019 [水木桶] all rights reserved. */ public class usercontroller { private userservice userservice = new userservice(); public user saveuser(string name) { return userservice.save(name); } }
1-1、依赖非静态类
package com.shuimutong.demo.junit; public class userservice { public user save(string name) { system.out.println("userservice--save--name:" + name); user u = new user(name); u.setid((long)(math.random() * 1000) + 2); return u; } }
1-2、相关类user
package com.shuimutong.demo.junit; public class user { private long id; private string name; public user(string name) { this.name = name; } public user() { } public string getname() { return name; } public void setname(string name) { this.name = name; } public long getid() { return id; } public void setid(long id) { this.id = id; } @override public string tostring() { return "user [id=" + id + ", name=" + name + "]"; } }
2、单测类
package com.shuimutong.demo.junit; import org.junit.assert; import org.junit.test; import org.junit.runner.runwith; import org.mockito.injectmocks; import org.mockito.mock; import org.mockito.mockito; import org.powermock.api.mockito.powermockito; import org.powermock.core.classloader.annotations.preparefortest; import org.powermock.modules.junit4.powermockrunner; /** * 参照1:https://www.jianshu.com/p/0c2480b1709e * 参照2:https://www.cnblogs.com/ljw-bim/p/9391770.html * @classname: usercontrollertest * @description:(这里用一句话描述这个类的作用) * @author: 水木桶 * @date: 2019年10月26日 下午4:13:51 * @copyright: 2019 [水木桶] all rights reserved. */ @runwith(powermockrunner.class) @preparefortest({usercontroller.class}) public class usercontrollertest { @mock private userservice userservice; @injectmocks private usercontroller usercontroller; @test public void saveuser() { string name = "jack"; //执行userservice的实际方法 powermockito.when(userservice.save(mockito.anystring())).thencallrealmethod(); user returnuser = usercontroller.saveuser(name); system.out.println("returnuser:" + returnuser); assert.asserttrue(returnuser.getid() > 1); long id = 1l; user u1 = new user(name); u1.setid(id); system.out.println("u1:" + u1); //mock userservice的方法 mockito.when(userservice.save(name)).thenreturn(u1); returnuser = usercontroller.saveuser(name); //verify验证mock次数 mockito.verify(userservice, mockito.times(2)).save(name); assert.assertequals(id, returnuser.getid()); assert.assertequals(u1, returnuser); system.out.println("returnuser:" + returnuser); } }
2-1、执行结果
userservice--save--name:jack
returnuser:user [id=51, name=jack]
u1:user [id=1, name=jack]
userservice--save--name:jack
returnuser:user [id=1, name=jack]
四、相关环境
1、依赖jar
<dependency> <groupid>junit</groupid> <artifactid>junit</artifactid> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupid>org.mockito</groupid> <artifactid>mockito-core</artifactid> <version>2.10.0</version> <scope>test</scope> </dependency> <dependency> <groupid>org.powermock</groupid> <artifactid>powermock-api-mockito2</artifactid> <version>2.0.2</version> <scope>test</scope> </dependency> <dependency> <groupid>org.powermock</groupid> <artifactid>powermock-module-junit4</artifactid> <version>2.0.2</version> <scope>test</scope> </dependency>
2、源码地址
https://gitee.com/simpleha/usedemo/tree/master/junit