Mockito(mockito使用心得)

2024-08-10 21:20:07 :20

mockito(mockito使用心得)

这篇文章给大家聊聊关于mockito,以及mockito使用心得对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。

本文目录

mockito使用心得

初次看到mockito的时候,是在开发者头条读的一篇关于github上2017年开源项目使用的jar包统计的文章。mockito是排名第二还是第三忘记了(第一是junit,可见对于单元测试的重视程度及java业内对单元测试框架选择的统一)。当时引起我注意的是因为mock这个词,正好前不久了解了下mock,于是就百度了mockito,发现mockito正好可以解决api调用的模拟问题,于是当晚就试了下这个工具。 对要模拟返回的类使用@Mock注解。如果需要测试的类不是被模拟的类,且需要被模拟的类注入的话使用@InjectMocks注解,还要调用MockitoAnnotations.initMocks方法注入。下为例子 模拟时分为两种语法 when、thenReturn、doReturn、是Mockito类里的静态方法,导包时候如果不加入static关键词的话,就需要加上Mockito. 类似Assert。 一开始一直运行不起来,各种找资料后,发现在类上加上如下注解就可以了。 但是在spring boot的其他测试类里,就算没有使用mock的话,不加上面注解的情况下是无法运行的,具体原因不明。 如上mockStr是模拟返回对象的字符串,转换为Map后,使用when(). thenReturn()将模拟的数据返回。 updatedAt 2018年03月23日14:17:12 今天又用了一下mockito,发现一些问题。先附上源码 userService是我需要的测试类,需要测试的方法是注册方法,需要用到短信校验,smsService是需要模拟的类,用于短信的发送和校验。因为我并不想要测试短信发送及校验的逻辑,我需要对smsService进行mock处理,再注入到userService。 这时候问题来了。我只把smsService做了mock,在测试注册方法的时候需要用到roleRepository的方法,去获取角色,而roleRepository报了NPE。userService使用了@InjectMocks注解,smsService因为mock注入进去了,而initService、userRepository、roleRepository等都无法注入。查了资料后,找不到方法可以将不想要mock的类自动注入进去。最后,只能再将roleRepository mock处理一下,注入到userService,返回角色。 此外,在查看官方文档额过程中,官方文档也给出了mockito干不了的事,这个可以解释 一些思考力 的第三点 以上是github上mockito wiki里的Remember 在FAQ中,也写了mockito的其他一些问题 No. Mockito prefers object orientation and dependency injection over static, procedural code that is hard to understand & change. If you deal with scary legacy code you can use JMockit or Powermock to mock static methods. No. From the standpoint of testing... private methods don’t exist. More about private methods here . No. You can stub it, though. Verification of toString() is not implemented mainly because: When debugging, IDE calls toString() on objects to print local variables and their content, etc. After debugging, the verification of toString() will most likely fail. toString() is used for logging or during string concatenation. Those invocations are usually irrelevant but they will change the outcome of verification.

mock单元测试 mockito实践

@Rule public MokitoRule rule = MockitoJUnit.rule(); 注意这里的修饰符public,如果没有这个修饰符的话使用mock测试会报错  @Rule  public ExpectedException thrown = ExpectedException.none(); 可以选择忽视抛出的异常?(我是这么理解的不知道是否正确) 这里我还没有看juint执行的逻辑,只是看了mock环境下获取注解创建mock对象,并将mock的对向注入到@Injectmocks的目标测试对象中去的逻辑。 使用的jar包版本是junit.junit.4.11,org.powermock.powermock-api-mockito.1.6.6 创建一个interface用于目标测试类的filed的type。 创建一个目标测试类,其中声明filed的type为上面的interface的type 最后创建一个测试用例对象用于测试目标测试类我从rule对象执行的时候开始追踪,junit的运行原理略过其中的testClass就是测试用例,MyMockTest的实例,annotationEngine是默认的注解驱动InjectingAnnotationEngine, 这个方法的内部获取测试用例的type,获取注解驱动,并判断是否是默认的注解驱动,可以自定义注解驱动?(暂时我还办不到),之后注解驱动执行InjectingAnnotationEngine.process 内部只有两个方法,从名字和其上的注释可以知道 processIndependentAnnotations处理独立的filed,其实就是测试用例中有@mock注解的filed,这里就是a和b。processInjectMocks处理依赖于独立mock对象的filed,就是测试用例中有@InjectMocks注解的filed,依赖于mock对象的目标测试类,这里就是DoMainObject,先看processInjectMocks入参分别为测试用例的type,和instance,方法中只有一个循环,在循环的内部处理三件事 1delegate.process(classContext, testInstance);委派对象处理@Mock,@Captor等注解, 2spyAnnotationEngine.process(classContext, testInstance);监视注解驱动处理@Spy注解 3获取测试用例的父类,赋值给原来的变量 4如果Class的type为Object,跳出循环 这个方法就是先处理自己的独立注解,然后去处理父类的独立注解,如此往复直到父类为Object源类。这个方法参数还是Class的type和Class 的instance, 处理过程是获取instance的所有field就是所有的属性,然后循环获取filed的上的所有注解,更具注解和field尝试创建mock对象,这里最后的创建对象时使用cblib创建代理对象,最后创建一个Setter对象将创建的cglib代理对象mock对象,set进instance的field中去,即完成了一个测试用例中的属性的注入(spring的bean注解注入方式是不是也是如此呢,所有的基于注解的实现原理是否基本类似于此呢) 这里只关注两个方法createMockFor和FieldSetter(testInstance, field).set(mock) createMockFor方法的流程比较复杂,这个方法的内部有两个方法,在这个方法中对annotationd的类型与已有的注解处理器对象集合进行判断是否包含,如果包含取出对应的处理器对象,如果不包含空实现一个注解处理器实现process方法返回为null。也就是说在DefaultAnnotationEngine对象的实例中只处理特定的注解生成其mock代理对象。 这个注解处理器的集合是在4中创建了deletage时创建了DefaultAnnotationEngine对象,然后在其构造方法中调用了注册注解驱动方法 private final Map, FieldAnnotationProcessor?》 annotationProcessorMap = new HashMap, FieldAnnotationProcessor》();根据获取的annotationProcess对象执行process方法,如果不是从map中获取的那么返回值就是null,在本测试中就是@mock的方法返回了MockAnnotationProcessor类型的注解驱动,Mockito.mock(field.getType(), mockSettings);这个就是最后创建mock的cglib代理对象的方法,对这个方法暂时就不继续追踪了, 现在我们已经将一个@Mock注解下的测试类中的field建立好了,让我们回到5的process方法中,能看见这个步骤就是重复的执行这段逻辑: 获取field的所有注解,调用createMockFor方法,然后在此方法中和DefaultAnnotationEngine预置的FieldAnnotationProcessor 实现类型集合做匹配,满足的获取指定的注解处理器创建对应的mock对象。不满足的创建一个匿名子类,其中实现的方法指定返回null。以此将@Mock等注解和其他注解区分开来,只创建@Mock和@Captor等独立的注解。如此步骤processIndependentAnnotations.process()就完成了。 spyAnnotationEngine.process的执行类似,但是这个注解处理类是使用反射去根据类型创建一个真实的实例对象返回而不是创建一个mock的cglib对象。 现在我们完成了processIndependentAnnotations,来看看现在的测试用例instance可以看到现在a,b使用@Mock注解的field已经存在cglib的代理对象了,使用@InjectMocks的doMainObject暂时还是null,现在来看processInjectMocks方法内部的核心方法是injectMocks,内部的逻辑从子类到父类最后到Object处理每个继承层级的@InjectMocks注解 方法内处理 1获取测试用例的Class类型 2创建一个Field对象的set集合 3循环处理 4将class中所有InjectMocks注解的field放到mockDependentFields集合中 5将创建的mock对象添加到mocks集合中 6Class类型是Object跳出循环 7创建@InjectMock注解修饰的field 这是根据依赖创建目标测试类的mock对象。 最后方法完成的时候可以看到目标测试类创建完成,依赖a,b也已经注入。 没有去追踪Junit和cglib只是将中间mock的注解的过程进行了追踪: 基本就是先创建mock对象,然后将根据依赖创建@InjectMocks的目标测试类对象 其中注解的区分 1@InjectMocks和其他类型不同, 2@Spy和@Mock,@Captor等注解不同 在使用的过程中Rule一定要是pulic修饰的 在使用mockito的时候还出现了mock的对象在测试的时候报空指针的问题,我追踪后发现是同类型的interface在注入@InjectMocks修饰的主目标对象的时候是有排序的,会根据测试类中的filedName进行排序依次向下注入,解决办法就是把@InjectMocks的所有field都进行mock。

Java中mockito类库有神马作用 其中的whitebox类又有何用 来高人解释一哈子~~

有点类似于Maven举个例子,比如你跑一个测试case去测试A类的f方法,但是这个A类依赖于很多其他的类才能正常运行,其他类有依赖了很多类。很麻烦,mockito就能创建一些中间对象,来替代你需要的类。whitebox 是白盒测试,比较高级的测试,需要对代码结构,逻辑都很清楚,不同于黑盒测试,只要测试功能是否正常

mockito如何查看是否成功

mockito查看成功的办法:项目右键点击BuildPath选项点击AddExternal Archives导入成功的。

***隐藏网址***

linux API:

在linux中,用户编程接口API遵循了UNIX中最流行的应用编程界面标准---POSIX标准。POSIX标准是由IEEE和ISO/IEC共同开发的标准系统。

该标准基于当时现有的UNIX实践和经验,描述了操作系统的系统调用编程接口API,用于保证应用程序可以在源程序一级上在多种操作系统上移植运行。这些系统调用编程接口主要是通过C库来实现的。

Mockito的参数匹配

上篇我们已经说过, mockito 中可以控制mock对象的方法,返回我们想要的值,而无需真正执行它。 使用方法是 doReturn(...).when(mockObject).invokeMethod(...params) 其中 传入调用方法中的参数,可以使用Mockito中的 any() 来做参数的匹配,代表任意的值,还有 anyString() , anyInt() , any(Class《T》 clazz) 等,具体可以查看 org.mockito.Matchers 。 这里我经常用到的一个是 any(Class《T》 clazz) ,传入任意一个特定类型的对象,控制方法的返回值。那如果再细化灵活一些,要根据对象的某一个属性的取值来进行匹配呢?比如要传入 Person 这个对象,测试方法要根据性别来做出不同的返回,应该怎么写参数匹配?Mockito为我们提供了 ArgumentMatcher 的方法。具体使用如下, 参考:***隐藏网址***

Mockito和嵌套的方法调用问题,怎么解决

Jmock和Mockito是常用的mock工具,Jmock功能相当强大,也比较容易用。Mockito 在处理多层嵌套时比较麻烦,下面说明了这种场景的主要用法。不过建议不是用jmock。

package com.jd.test; import static org.junit.Assert.assertEquals;import static org.mockito.Matchers.anyLong;import static org.mockito.Mockito.when; import javax.annotation.Resource; import org.junit.Before;import org.junit.Test;import org.junit.runner.RunWith;import org.mockito.InjectMocks;import org.mockito.Mock;import org.mockito.MockitoAnnotations;import org.mockito.Spy;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.jd.test.service.CustomerBusiness;import com.jd.test.service.FeeBusiness;import com.jd.test.service.OrderBusiness;import com.jd.test.service.ProductBusiness;import com.jd.test.service.impl.FeeBusinessImpl; @RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "/spring-config.xml")public class MockitoTest { @Resource@InjectMocksprivate ProductBusiness injectProductBusiness;@Mockprivate OrderBusiness orderBusiness;@Resource@InjectMocksprivate CustomerBusiness customerBusiness;@Spyprivate FeeBusiness feeBusiness = new FeeBusinessImpl(); @Beforepublic void setup() {MockitoAnnotations.initMocks(this);}/** * 自动注入mock管理的bean. 解决二层和多层bean嵌套的部分mock场景。即injectProductBusiness-》customerBusiness-》feeBusiness 时,如果想mock feeBusiness中的某个方法.  *  * @Resource@InjectMocksprivate ProductBusiness injectProductBusiness;@Resource@InjectMocksprivate CustomerBusiness customerBusiness;@Spyprivate FeeBusiness feeBusiness = new FeeBusinessImpl(); *  *  @InjectMocks 标签会自动填充带@Spy和@Mock标签的bean. *  @Spy 被它代理的bean,默认执行原生方法。但可以在后期mock想要的方法。 *  @Mock 相当于mockito帮助简单的实例化bean,因此无法执行原生方法。适用于整个bean都mock,如DAO。 *    *  同时可以结合spring一起管理bean.对bean的管理应该是spring先进行一系列的如初始化bean操作,然后mockito会引用spring生成的bean,并对bean里的指定field进行重新注入。以达到实现部分mock功能 。 */@Testpublic void injectClass() {when(feeBusiness.getFee(anyLong())).thenReturn("spy inject");assertEquals(injectProductBusiness.getCustomerName(1), "productBusinessimpl-》null");assertEquals(injectProductBusiness.getCustomerPhone(2),"productBusinessimpl-》CustomerBusinessImpl-》2");assertEquals(injectProductBusiness.getOrderFee(3),"productBusinessimpl-》CustomerBusinessImpl-》spy inject");} }

关于mockito和mockito使用心得的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

mockito(mockito使用心得)

本文编辑:admin
: mockito,
Copyright © 2022 All Rights Reserved 威海上格软件有限公司 版权所有

鲁ICP备20007704号

Thanks for visiting my site.