很久不写博客了,经常搜索前辈和晚辈写的问题解决方案,得到很多帮助,也受益匪浅,所以也时常感到愧疚。那么接下来一段时间,我也分享一些技术点,问题方案吧。闻道有先后,术业有专攻。也希望我们都能保持一颗谦卑的心向身边或网络上的人学习,因为每个人都有自己的闪光点……
本篇单元测试暂时局限于mock、powermock,引用的jar包,大家自行百度吧。很简单。demo样例,网上也多,后续我也可以给大家一些代码样例。
一、常见问题与解决方案
1、when().thenreturn()中常见问题
1.1. mock模拟的请求参数是对象,传入对象的每个元素值都对,但是报错
sysinfo sysinfo = new sysinfo();
sysinfo.setact("abc");
when(systeminfoservice.querysysparamscount(sysinfo)).thenreturn(1);
问题:功能代码运行时生成的对象和mock传入的对象,对象内每个元素的值都一样,但是返回异常。
解决方案:请求对象对应的类sysinfo没有重写equals和hashcode方法。
传入的对象是map,会有这种问题吗?
不会。
1.2. 请求参数除了可以用any(),anystring,还可以用什么替代?
解决方案:还可以用any(类名.class)
1.3. 模拟while、for循环的参数时,如何跳出循环?
解决方案:thenreturn后再增加一个thenreturn,意思就是返回值有多种情况。第二次遍历时,就会变成下一个返回值。
例如:
when(systeminfoservice.querysysparams(any()).thenreturn(sysinfolist ).thenreturn(sysinfolist2 );
1.4. 静态变量的mock——mockedstatic,多个类使用时,出现already regestered的问题
例如声明了一个mockedstatic
mockedstatic<dateutil> dateutilmockedstatic;
解决方案:
有可能是因为静态变量没关闭,那么就在调用的方法内执行到最后调用这个静态mock的close方法,或者在@after对应方法内,调用它的close方法。
还有一种更容易发生的错误,前面没加this
生成这个变量,关闭它,都要在前面加“this.”
也就是
mockedstatic<dateutil> dateutilmockedstatic;
@before
public void setup() {
openmocks(this);
this.dateutilmockedstatic = mockstatic(dateutil.class);
}
@after
public void destroy(){
this.dateutilmockedstatic.close();
}
why?应该是因为,我们声明的静态变量不加this,就是属于整个包或者整个项目,所以导致的重复注册问题。
1.5. 对于同一个方法调用,返回的类型不一致,如何mock?
对于这种情况,可以用when().thenreturn(map).thenreturn(intnum).thenreturn(str)...thenreturn(map)形式,返回功能代码逐次调用的同名方法不同返回值的对应返回值。
注意:这种返回mock,针对每一次功能内某个总方法的调用来都需要mock一次。
2. reflecttestutil作为反射的使用
3. mockstatic
4.
二、注意事项:
1、我们是写单元测试的,不是写功能代码的,功能业务代码,一般是不能因为写单元测试去改动的!!!这一点非常重要。
2、单元测试代码也要尽可能优化,尽量不要为了简单,把对一个公共方法的单元测试,分几个好几个方法去mock测试,这样产生了大量冗余代码,也会增加编译运行时间,降低项目性能与开发效率。
三、单元测试中idea工具调优与使用技巧
1、如果是gradle作为jar包版本工具,要配置gradle,让它编译和运行都在idea上直接执行,而不是在gradle工具上执行。
2、多个单元测试代码写完,可以选择test的根目录、主目录,执行单元测试。这样可以发现多个单元测试文件同时执行时的问题,及时改正,快速提高单元测试覆盖率。
四、单元测试代码样例
package com.example.demo;
import org.assertj.core.util.dateutil;
import org.junit.after;
import org.junit.before;
import org.junit.test;
import org.mockito.injectmocks;
import org.mockito.mockedstatic;
import static org.mockito.argumentmatchers.anymap;
import static org.mockito.mockito.mockstatic;
import static org.mockito.mockito.when;
import static org.mockito.mockitoannotations.openmocks;
/**
* @author henrylee
* @description todo
* @date 2024/5/27 22:16
* @version 1.0
*/
public class mycontrollertest {
@injectmocks
private mycontroller mycontroller;
mockedstatic<dateutil> dateutilmockedstatic;
@before
public void setup() {
openmocks(this);
this.dateutilmockedstatic = mockstatic(dateutil.class);
}
@after
public void destroy(){
this.dateutilmockedstatic.close();
}
@test
public void testcontroller() {
when(mycontroller.getmsg()).thenreturn(null);
}
}
发表评论