场景1:某三方接口所有方法都需要Mock

实现方式1-配置configrution bean

实现方式2-在application context中配置mock bean

场景2:某三方接口部分方法mock

实现方式1-spy方式:

实现方式2-callRealMethod():

场景3:影响范围只在单个测试类

实现方式1-使用ReflectionTestUtils解决依赖注入Mock对象

实现方式2-官方介绍的@mock,@injectMock方式

场景4.mock代理类

实现方式1-通过AddtionalAnswer.delegateto(instance)

场景1:某三方接口所有方法都需要Mock

实现方式1-配置configrution bean

step1:创建一个类如下:

@Configuration

public class WithdrawConfiguration {

@Bean

@Primary

public SauronBankService sauronBankService() {

SauronBankService mock = mock(SauronBankService.class);

BankCardDTO t = new BankCardDTO();

t.setBankId((short) 11);

t.setCardholder("hehe");

t.setCardId("32423423423");

t.setBankName("中国银行 ");

t.setAcc_type((byte) 1);

t.setBranch_bank_name("武汉分行");

t.setProvince("湖北省");

t.setCity("武汉市");

when(mock.queryBankCard(anyInt(), anyLong(), Mockito.<String> any()))

.thenReturn(t);

return mock;

}

@Bean

@Primary

public MasspayClient masspayClient() {

// then return this.

MasspayClient client = Mockito.mock(MasspayClient.class);

MasspayResult<WithdrawResponse> withdrawResponseMasspayResult = new MasspayResult<>(

ResultCode.SUCCESS);

when(client.callLadon(any(WithdrawRequest.class)))

.thenReturn(withdrawResponseMasspayResult);

MasspayResult<CancelResponse> cancelResponseMasspayResult = new MasspayResult<>(

ResultCode.SUCCESS);

when(client.cancelCallLadon(any(CancelRequest.class)))

.thenReturn(cancelResponseMasspayResult);

return client;

}

}

step2.在application context中加载如下:

实现方式2-在application context中配置mock bean

step1:pom文件中加载mockito dependency

step2:在application context中声明mock bean,参考如下:

<bean id="mockOrderManageFacade" class="org.mockito.Mockito"

factory-method="mock">

<constructor-arg value="me.ele.transcore.comm.facade.api.OrderManageFacade">

</constructor-arg>

</bean>

注意事项:

<!-- id必须和biz中autowired的属性值一致,然后在测试类中@Resource该对象,stub该对象的方法指定返回数据 -->

<!-- 对其他测试类的影响:有关联测试类调用该接口时,接口中的其他方法默认返回null;解决影响:在其他相关联的测试指定返回值 -->

step3:在测试类中添加mock代码,参考如下:

MockitoAnnotations.initMocks(this);//初始化mock bean

WithdrawCancelCallBackResponse mockResponse = new WithdrawCancelCallBackResponse();

mockResponse.setResultCode(

ResultCodeEnum.FAIL_WITHDRAW_CALLBACK_AMOUNT_NO_CONSISTENT

.getKey());//

Mockito.when(mockOrderManageFacade.withdrawCancelCallBack(

Mockito.any(WithdrawCancelCallBackRequest.class)))

.thenReturn(mockResponse);//mock为期望的response

场景2:某三方接口部分方法mock

  1. 部分mock解释说明:部分mock是说一个类的方法有些是实际调用,有些是使用mockito的stubbing(桩实现)
  2. mockito实现部分mock的两种方式:spy和callRealMethod()
  3. Spy类就可以满足我们的要求。如果一个方法定制了返回值或者异常,那么就会按照定制的方式被调用执行;如果一个方法没被定制,那么调用的就是真实类的方法。
  4. 如果我们定制了一个方法A后,再下一个测试方法中又想调用真实方法,那么只需在方法A被调用前,调用Mockito.reset(spyObject)。

实现方式1-spy方式:

@Test

public void spy_Simple_demo(){

List<String> list = new LinkedList<String>();

List<String> spy = spy(list);

when(spy.size()).thenReturn(100);

spy.add("one");

spy.add("two");

/*      spy的原理是,如果不打桩默认都会执行真实的方法,如果打桩则返回桩实现。

可以看出spy.size()通过桩实现返回了值100,而spy.get(0)则返回了实际值*/

assertEquals(spy.get(0), "one");

assertEquals(100, spy.size());

}

注意事项:当调用方法如when().thenReturn()时,实际上还是调用了实际方法。

参考如下:

@Test

public void spy_Procession_Demo() {

Jack spyJack = spy(new Jack());

//使用spy的桩实现实际还是会调用stub的方法,只是返回了stub的值

when(spyJack.go()).thenReturn(false);

assertFalse(spyJack.go());

//不会调用stub的方法

doReturn(false).when(spyJack).go();

assertFalse(spyJack.go());

}

实现方式2-callRealMethod():

package callRealMethod;

import org.junit.Test;

import static org.mockito.Mockito.*;

public class CallMethodDemo {

@Test

public void callRealMethodTest() {

Jerry jerry = mock(Jerry.class);

doCallRealMethod().when(jerry).doSomeThingA();

doCallRealMethod().when(jerry).doSomeThingB();

jerry.goHome();

verify(jerry).doSomeThingA();

verify(jerry).doSomeThingB();

}

}

class Jerry {

public void goHome() {

doSomeThingA();

doSomeThingB();

}

// real invoke it.

public void doSomeThingB() {

System.out.println("good day");

}

// auto mock method by mockito

public void doSomeThingA() {

System.out.println("you should not see this message.");

}

}

场景3:影响范围只在单个测试类

优点:mock对象影响范围只在单个测试类,不影响其他测试类。

实现方式1-使用ReflectionTestUtils解决依赖注入Mock对象

@Component

public class WithdrawApplicationTest extends AccountWithdrawFacadeBaseTest {

@Captor

private ArgumentCaptor<WithdrawApplicationRequest> captor;

@Mock

private CheckPasswordComponent mockCheckPasswordComponent;

@Autowired

private CheckPasswordComponent checkPasswordComponent;

@Autowired

private AccountWithdrawWithoutLadonBiz acccountWithdrawWithoutLadonBiz;

@Autowired

private AccountWithdrawFacade withdrawFacade;

@Test

public void withdrawTest() {

WithdrawApplicationRequest applyReq = new WithdrawApplicationRequest();

applyReq.setAccountType(TYPE);

applyReq.setCustomerId(ZEUS_CUSTOMER_ID);

applyReq.setRequestPartyId(ZEUS_SOURCE_PARTY_ID);

applyReq.setSourcePartyId(ZEUS_SOURCE_PARTY_ID);

applyReq.setTransactionChannel("h5");

applyReq.setPassword(ZEUS_PASSWORD);

applyReq.setPartyTransactionId(

new Timestamp(System.currentTimeMillis()).toString());

applyReq.setPartyTransactionTime(

new Timestamp(System.currentTimeMillis()));

applyReq.setTransAmount(new BigDecimal("1000"));

applyReq.setSign(GenerateSignUtils.generateSign(applyReq,

"fd219e782ecebf0bc8f4a83e43248b45"));

given(mockCheckPasswordComponent.restCountByPassword(Mockito.anyInt(),

Mockito.anyLong(), Mockito.anyByte())).willReturn(3);

WithdrawApplicationResponse response = withdrawFacade

.withdrawApplication(applyReq);

verify(mockCheckPasswordComponent, times(1)).restCountByPassword(

Mockito.anyInt(), Mockito.anyLong(), Mockito.anyByte());

Assert.assertEquals(response.getRestAttempts(), 3);

System.err.println(JsonUtil.toFormatJson(response));

Assert.assertEquals(response.getTransactionResultDescription(), "成功");

}

@BeforeClass

private void beforeClass() {

MockitoAnnotations.initMocks(this);

try {

ReflectionTestUtils.setField(

AopTargetUtils.getTarget(acccountWithdrawWithoutLadonBiz),

"checkPasswordComponent", mockCheckPasswordComponent);

} catch (Exception e) {

logger.error("", e);

}

}

@AfterClass

public void clearMocks() throws Exception {

ReflectionTestUtils.setField(

AopTargetUtils.getTarget(acccountWithdrawWithoutLadonBiz),

"checkPasswordComponent", checkPasswordComponent);// 还原为真实bean,不影响其他case

}

}

实现方式2-官方介绍的@mock,@injectMock方式

说明:据实验,这种模式碰到多层内嵌bean时不生效,所以暂不举例说明,参考如下文档。

官方文档参考:https://static.javadoc.io/org.mockito/mockito-core/2.10.0/org/mockito/Mockito.html

场景4.mock代理类

实现方式1-通过AddtionalAnswer.delegateto(instance)

转载:https://www.cnblogs.com/danqiu/p/7531538.html

Mockito各场景使用介绍的更多相关文章

  1. List集合的总结和应用场景的介绍

    1.List的整体介绍 List 是一个接口,它继承于Collection的接口,它代表着有序的队列.list的实现类对象中每一个元素都有一个索引值,能够按照索引值进行元素查找. AbstractLi ...

  2. PHP的设计模式及场景应用介绍

    有大量的文章解释什么是设计模式,如何实现设计模式,网络上不需要再写一篇这样的文章.相反,在本文中我们更多的讨论什么时候用和为什么要用,而不是用哪一个和如何使用. 我将会为这些设计模式描绘不同的场景和案 ...

  3. 消息中间件activemq的使用场景介绍(结合springboot的示例)

    一.消息队列概述 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题.实现高性能,高可用,可伸缩和最终一致性架构.是大型分布式系统不可缺少的中间件. 目前在生产环境,使 ...

  4. 从Client应用场景介绍IdentityServer4(一)

    原文:从Client应用场景介绍IdentityServer4(一) 一.背景 IdentityServer4的介绍将不再叙述,百度下可以找到,且官网的快速入门例子也有翻译的版本.这里主要从Clien ...

  5. Android线程管理之ThreadLocal理解及应用场景

    前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣 ...

  6. RunLoop 总结:RunLoop的应用场景(一)

    参考资料 好的书籍都是值得反复看的,那好的文章,好的资料也值得我们反复看.我们在不同的阶段来相同的文章或资料或书籍都能有不同的收获,那它就是好文章,好书籍,好资料.关于iOS 中的RunLoop资料非 ...

  7. Netsharp介绍

    1.1     Netsharp是什么 Netsharp定义: Netsharp业务基础平台 = 1.系统框架 + 2.元数据 + 3.平台工具 + 4.基础业务 + 5.二次开发 此五个概念请参考什 ...

  8. cocos2d-x中的导演、场景、层和精灵

    场景(Scenes) 场景在cocos2d-x中是CCScene类实现的,是应用程序流中独立的一部分.一个cocos2dx应用程序可以有许多场景,但是在某一时刻,只有一个场景在运行. 比如,你有一个游 ...

  9. Mockito--完整功能介绍(转)

    public interface DBAccess { int delete(String moi,String moc) throws Exception; void create(String m ...

随机推荐

  1. MySQL是如何利用索引的

    http://fordba.com/spend-10-min-to-understand-how-mysql-use-index.html

  2. OFbiz--简单介绍

    一.简单介绍 OFBiz是一个很著名的电子商务平台,是一个很著名的开源项目,提供了创建基于最新J2EE/XML规范和技术标准,构建大中型企业级.跨平台.跨数据库.跨应用server的多层.分布式电子商 ...

  3. rcp(插件开发)点击按钮出现 The chosen operation is not enabled 解决办法

    别的项目组,遇到以下错误信息: 首先看一下log日志里的异常信息,估计就知道是什么问题了. 项目组遇到的这个错误是source 指向错误 找不到相关的class.

  4. Leetcode 234 Palindrome Linked List 复杂度为时间O(n) 和空间(1)解法

    1. 问题描写叙述 给定一个单链表,推断其内容是不是回文类型. 比如1–>2–>3–>2–>1.时间和空间复杂都尽量低. 2. 方法与思路 1)比較朴素的算法. 因为给定的数据 ...

  5. FTP主动模式与FTP被动模式所需的端口

    转载自:http://www.mofang.net/article/272/sort0963/2008/Article_11581.shtml FTP是仅基于TCP的服务,不支持UDP. 与众不同的是 ...

  6. AngularJS路由系列(4)-- UI-Router的$state服务、路由事件、获取路由参数

    本系列探寻AngularJS的路由机制,在WebStorm下开发.主要包括: ● UI-Router的$state服务● UI-Router的路由事件● UI-Router获取路由参数 Angular ...

  7. 如何选择使用IEnumerable, ICollection, IList

    IEnumerable, ICollection, IList,每种接口只适合某些特定场景,如何区别使用呢? IEnumerable接口,只提供了一个获取迭代器的方法,这也是为什么可以使用foreac ...

  8. delphi连接mysql不用添加DSN(mysql connector odbc 5.1版)

    一.下载安装mysql驱动http://mysql.com/downloads/connector/odbc/二.添加adoconnection,adoquery,使用以下连接字符串http://ww ...

  9. NSNotificationCenter消息注册与撤销

    苹果的消息机制是个非常好用的东西,当需要在类的各个实例之间传递消息或者写一些事件驱动的程序时,绝对是个不错的工具.但是使用时一不小心就会造成引用已经被dealloc的对象的错误,引起程序崩溃.于是,在 ...

  10. 教你调用数据库读取短信 记事本 通讯录文件,让ios5的短信恢复到ios4

    由于高版本的ios固件向下恢复到低版固件时无法通过itunes恢复备份,所以一些数据,比如SMS需要通过提取文件的方式单独进行备份恢复特别是ios5的短信,之前很是头痛,直接将文件恢复到指定目录修改权 ...