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条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8编译安装MySQL8.0.19
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程