Mockito框架里面的@Mock注解原理
@Mock注解就是其实就是用cglib的原理帮我们new了一个@Mock注解作用类的子类,什么意思呢,往下看
首先是Company,此时hh方法返回值是”字符串”,
package com.one.util; import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class Company { private String name; public String hh(){ return "字符串"; } }
User类,mm()的返回值就是Company类的hh()返回值
package com.one.util; import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class User { private Company company; private int age; public String mm(){ return company.hh(); } }
然后UserTest类如下,此时可以看到下面的Company上面放了@Mock注解,他的作用就是帮我们生产一个Company类的子类(假如是CompanyZi),然后使用多态赋值给下面的company(就像这样Company company=new CompanyZi),而且这个ComanyZi类里面的hh()方法的返回值是null,为什么这样说呢,我们看下面的结果
package com.one.util; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import static org.assertj.core.api.Assertions.catchThrowable; @RunWith(MockitoJUnitRunner.class) public class UserTest { @Mock private Company company; private User user; @Before public void setUp() { user = new User(company, 1); } @Test public void tt() { catchThrowable(() -> { String mm = user.mm(); System.out.println(mm); }); } }
此时可以看到结果是null
简单来说上面的代码可以变成下面这样
首先是Company,此时hh方法返回值是”字符串”,
package com.one.util; import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class Company { private String name; public String hh(){ return "字符串"; } }
User类,mm()的返回值就是Company类的hh()返回值
package com.one.util; import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class User { private Company company; private int age; public String mm(){ return company.hh(); } }
然后UserTest类如下,此时下面的类ComapanyZi就相当于上面的被@Mock注解的company的最终被new的对象,只不过@Mock注解帮我做了下面的CompanyZi这个类,此时可以看到下面的ComapanyZi返回的是null
package com.one.util; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import static org.assertj.core.api.Assertions.catchThrowable; @RunWith(JUnit4.class) public class UserTest { class ComapanyZi extends Company{ public ComapanyZi(String name) { super(name); } public String hh(){ return null; } } private User user; @Test public void name() { user=new User(new ComapanyZi("zi"),1); Throwable throwable = catchThrowable(() -> { System.out.println(user.mm()); }); } }
此时可以看到结果是null
我们可以验证上面的结论
就是给@Mock注解的类添加一个final,然后在运行的时候就报错了
Company类,此时可以看到Compan已经被final修改了
package com.one.util; import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public final class Company { private String name; public String hh(){ return "字符串"; } }
User类
package com.one.util; import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class User { private Company company; private int age; public String mm(){ return company.hh(); } }
然后测试如下,然后运行下面的name方法,然后结果如下所示
package com.one.util; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class UserTest { @Mock private Company company; private User user; @Before public void setUp(){ user = new User(company,1); } @Test public void name() { user.mm(); } }
此时可以看到报错了,说Company不能被final修改,者更好符号cglib的规则
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
5种JVM垃圾收集器特点和8种JVM内存溢出原因
先来看看5种JVM垃圾收集器特点 一、常见垃圾收集器 现在常见的垃圾收集器有如下几种:新生代收集器:SerialParNewParallel Scavenge老年代收集器:Serial OldCMSParallel Old堆内存垃圾收集器:G1每种垃圾收集器之间有连线,表示他们可以搭配使用。 二、新生代垃圾收集器 (1)Serial 收集器Serial 是一款用于新生代的单线程收集器,采用复制算法进行垃圾收集。Serial 进行垃圾收集时,不仅只用一条线程执行垃圾收集工作,它在收集的同时,所有的用户线程必须暂停(Stop The World)。就比如妈妈在家打扫卫生的时候,肯定不会边打扫边让儿子往地上乱扔纸屑,否则一边制造垃圾,一遍清理垃圾,这活啥时候也干不完。如下是 Serial 收集器和 Serial Old 收集器结合进行垃圾收集的示意图,当用户线程都执行到安全点时,所有线程暂停执行,Serial 收集器以单线程,采用复制算法进行垃圾收集工作,收集完之后,用户线程继续开始执行。 适用场景:Client 模式(桌面应用);单核服务器。可以用 -XX:+UserSerialGC 来选...
- 下一篇
一次性集中处理大量数据的定时任务,如何缩短执行时间?
作者:58沈剑 问题抽象:(1)用户会员系统;(2)用户会有分数流水,每个月要做一次分数统计,对不同分数等级的会员做不同业务处理;数据假设: (1)假设用户在100w级别;(2)假设用户日均1条流水,也就是说日增流水数据量在100W级别,月新增流水在3kW级别,3个月流水数据量在亿级别;常见解决方案:用一个定时任务,每个月的第一天计算一次。 //(1)查询出所有用户 uids[] = select uid from t_user; //(2)遍历每个用户 foreach $uid in uids[]{ //(3)查询用户3个月内分数流水 scores[]= select score from t_flow where uid=$uid and time=[3个月内]; //(4)遍历分数流水 foreach $score in scores[]{ //(5)计算总分数 sum+= $score; } //(6)根据分数做业务处理 switch(sum) 升级降级,发优惠券,发奖励; } 一个月执行一次的定时任务,会存在什么问题?计算量很大,处理的数据量很大,耗时很久,按照水友的说法,需...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS8编译安装MySQL8.0.19
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Red5直播服务器,属于Java语言的直播服务器