转载:https://blog.csdn.net/paincupid/article/details/53561435

1、引入mockito jar包

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>2.0.2-beta</version>
</dependency>

2、对于Mockito而言,有两种方式创建:

  1. mock为一个interface提供一个虚拟的实现,
  2. spy为object加一个动态代理,实现部分方法的虚拟化
  • @Mock,被标注的属性是个mock
  • @Spy,被标注的属性是个spy,需要赋予一个instance。提供了一种对真实对象操作的方法
  • @InjectMocks,将本test中的mock或者spy注入到被标注的属性中,根据构造函数的参数名,或者setter,或者私有属性名。

3、如果你使用spring,上述代码还可以进一步简化,因为Mockito提供了factory的方法用来创建mock和spy。

### 正常的bean声明

<bean id=”svc” class=”Svc”>
<bean id=”dao1” class=”…”>
<bean id=”dao2” class=”…”>

mock

<bean id="operationService" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="com.paincupid.api.operation.OperationService" />
</bean>

请注意到svc不变化,mock将自动注入进入。这是因为spring的bean容器,如果id一样,后声明的bean会覆盖前面的bean。

spy

<bean id="daoInst"  class="DaoInstance"></bean>
<bean id="dao2" class="org.mockito.Mockito" factory-method="spy">
<constructor-arg ref="daoInst"></constructor-arg>
</bean>

同样svc不变化,直接注入。请注意spy需要获得一个实例。

4、如果不用xml的话,可以在java中注解的方式引入

FinanceServiceTest.java

package com.paincupid.springmvc.mybaitsgenerator.persistence.test;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import com.paincupid.springmvc.base.JUnitDaoBase;
import com.paincupid.springmvc.finance.domain.Finance;
import com.paincupid.springmvc.finance.persistence.FinanceMapper;
import com.paincupid.springmvc.finance.service.FinanceService; public class FinanceServiceTest extends JUnitDaoBase{ @InjectMocks
FinanceService service; @Mock
FinanceMapper mapper; @Before
public void setUp() {
MockitoAnnotations.initMocks(this);
} @Test
public void selectByExampleTest() {
Finance f = Mockito.mock(Finance.class);;
f.setBak("bak");
f.setConsumer("consumer");
String id = "1"; Mockito.when(mapper.searchFinanceById(id)).thenReturn(f);
Finance returnF = service.searchFinanceById(id);
Mockito.verify(mapper).searchFinanceById(id); Assert.assertEquals(f.getConsumer(), returnF.getConsumer()); }
}

JUnitDaoBase.java

package com.paincupid.springmvc.base;

import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional; @RunWith(SpringJUnit4ClassRunner.class)
//使用classpath,会自动去class下的目录去找,所以暂时把它放到了resource目录下。
@ContextConfiguration(locations = {"classpath:/junitTestContext.xml"})
@Transactional
public class JUnitDaoBase extends AbstractTransactionalJUnit4SpringContextTests { }

配置文件junitTestContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
"
default-lazy-init="true"> <!-- 扫描service、dao组件 -->
<context:component-scan base-package="com.paincupid.springmvc.*.service,com.paincupid.springmvc.*.persistence" /> <!-- 使用jackson 支持json Java中直接返回类,而不用再使用Json转换 2015.12.27 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonHttpMessageConverter" />
</list>
</property>
</bean>
<bean id="jsonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean> <!-- 分解配置 jdbc.properites -->
<!-- <context:property-placeholder location="classpath:jdbc.properties"
/> -->
<!-- 数据源BoneCP -->
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/lee" />
<property name="username" value="lee" />
<property name="password" value="eee" />
<property name="maxConnectionsPerPartition" value="30" />
<property name="minConnectionsPerPartition" value="10" />
<property name="partitionCount" value="1" />
<property name="acquireIncrement" value="5" />
<property name="statementsCacheSize" value="100" />
</bean>
<!-- sessionFactory 将spring和mybatis整合 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- value可以填多个 -->
<property name="typeAliasesPackage"
value="com.paincupid.springmvc.system.domain,com.paincupid.springmvc.test.domain
,com.paincupid.springmvc.finance.domain" />
</bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.paincupid.springmvc.*.persistence" />
</bean> <!-- 事务 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
scope="singleton">
<property name="dataSource" ref="dataSource"></property>
</bean> <tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="select*" read-only="true" />
<tx:method name="add*" isolation="READ_COMMITTED" rollback-for="Exception" />
<tx:method name="update*" isolation="READ_COMMITTED" rollback-for="Exception" />
<tx:method name="delete*" isolation="READ_COMMITTED" rollback-for="Exception" />
</tx:attributes>
</tx:advice>
<!-- 在service层实现事务控制 -->
<aop:config>
<aop:pointcut expression="execution(* com.paincupid.springmvc.*.service.*.*(..))" id="pointCut" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut" />
</aop:config>
</beans>

5、其它

验证调用次数

verify(mock1, timeout(100).times(2)).get(anyInt());

除了代码中的方法,Mockito 还提供了 
- never() 没有被调用,相当于times(0) 
- atLeast(N) 至少被调用N次 
- atLeastOnce() 相当于atLeast(1) 
- atMost(N) 最多被调用N次 
超时验证

通过 timeout 我们可以进行验证程序执行时间是否符合规则。 
方法调用顺序

Inorder 可以验证方法调用的顺序 
verifyNoMoreInteractions 和 verifyZeroInteractions

verifyNoMoreInteractions:查询是否存在被调用,但未被 verify 验证的方法

verifyZeroInteractions:verifyZeroInteractions 
ArgumentCaptor 参数捕获器 
可在验证时对方法的参数进行捕获,最后验证捕获的参数值。如果方法有多个参数都要捕获验证,那就需要创建多个ArgumentCaptor对象处理。

6、下载地址:

https://git.oschina.net/paincupid/springmvc.git

7、转载请注明出处:

http://blog.csdn.net/paincupid/article/details/53561435

Mockito单测,mock service层的mapper的更多相关文章

  1. Mockito鸡尾酒第一杯 单测Mock

    鸡尾酒 Mockito是Java的单元测试Mock框架. 它的logo是一杯古巴最著名的鸡尾酒Mojito, Mojito鸡尾酒,源自古巴的哈瓦那,带有浓厚的加勒比海风情. 并不浓烈,但是喝一杯下去, ...

  2. 使用Groovy+Spock轻松写出更简洁的单测

    当无法避免做一件事时,那就让它变得更简单. 概述 单测是规范的软件开发流程中的必不可少的环节之一.再伟大的程序员也难以避免自己不犯错,不写出有BUG的程序.单测就是用来检测BUG的.Java阵营中,J ...

  3. 深入理解--SSM框架中Dao层,Mapper层,controller层,service层,model层,entity层都有什么作用

    SSM是sping+springMVC+mybatis集成的框架. MVC即model view controller. model层=entity层.存放我们的实体类,与数据库中的属性值基本保持一致 ...

  4. spring service层单元测试

    service层测试较简单,目前大多数测试主要是针对public方法进行的.依据测试方法划分,可以分为两种:基于mock的隔离测试和基于dbunit的普通测试. mock隔离测试 配置pom.xml ...

  5. 基于Wiremock创建Mock Service平台

    转载:http://blog.csdn.net/liuchunming033/article/details/52399397 1.Wiremock工具介绍 一般开发项目都会分模块进行,比如都会把前端 ...

  6. 基于Wiremock创建Mock Service平台(转)

    本文链接:https://blog.csdn.net/liuchunming033/article/details/52399397                                   ...

  7. 039医疗项目-模块四:采购单模块—采购单的创建-----------Dao层,service层,Acion层

    我们根据数据库里面的表格:生成对应的Mapper接口文件和...Mapperxml文件: YYCGD:采购单模板表. YYCGD2014:采购单动态生成表,由存储过程生成. YYCGDMX:采购单明细 ...

  8. springboot 注册dao层 service 层

    可以使用三种注解来引入DAO层的接口到spring容器中.1.@Mapper,写在每一个DAO层接口上,如下: 2.@MapperScan和@ComponentScan两者之一.前者的意义是将指定包中 ...

  9. 使用Java函数接口及lambda表达式隔离和模拟外部依赖更容易滴单测

    概述 单测是提升软件质量的有力手段.然而,由于编程语言上的支持不力,以及一些不好的编程习惯,导致编写单测很困难. 最容易理解最容易编写的单测,莫过于独立函数的单测.所谓独立函数,就是只依赖于传入的参数 ...

随机推荐

  1. 北大 ACM 分类 汇总

    1.搜索 //回溯 2.DP(动态规划) 3.贪心 北大ACM题分类2009-01-27 1 4.图论 //Dijkstra.最小生成树.网络流 5.数论 //解模线性方程 6.计算几何 //凸壳.同 ...

  2. Linux网络编程--sendfile零拷贝高效率发送文件

    from http://blog.csdn.net/hnlyyk/article/details/50856268 Linux系统使用man sendfile,查看sendfile原型如下: #inc ...

  3. Win10系统下如何禁止同步主机session?windows 10禁止同步主机session的方法

    近来,有些刚刚升级Win10正式版的用户反映自己的电脑开机时有个同步主机session启动项占用了将近半分钟,而选择用360禁止后,下次会出现同步主机session3,再禁止下次又会出现同步主机ses ...

  4. AngularJS双向绑定,手动实施观察

    实现这样的一个需求:页面中某个地方显示某个文本框的值经过计算得到的结果,而且是文本框值每次变化显示的计算结果也跟着动态变化. 在controller中可以声明一个对象,它的一个字段用来存储初始值: $ ...

  5. Object [object Object] has no method 'live'

    用了2个jquery的2个文件: <script src="~/Scripts/jquery-1.10.2.js"></script> <script ...

  6. 【linux】find命令仅返回文件名 不用返回完整的文件路径

    正常查询 find /apps/swapping -name '*swapping*.jar' 在/apps/swapping 目录下 查找 文件名为 '包含swapping的并且以.java结尾的文 ...

  7. android studio build.gradle中 project.ANDROID_BUILD_SDK_VERSION

    1.メニューの [File] -> [Import Module]2.Source directory に先ほど解凍したディレクトリを指定3.「facebook」 を選択した状態に Finish ...

  8. SeekBar的用法和自定义滑块的样式

    SeekBar继承自ProgressBar,所以基本一样,我们自定义一般也就是顶一个滑块的图片而已. 布局文件 <RelativeLayout xmlns:android="http: ...

  9. 使用ASP.NET读取word2003文档

    直接使用.NET 读取doc文档. http://www.codeproject.com/Articles/22738/Read-Document-Text-Directly-from-Microso ...

  10. Python 的 Flask 框架安装应用

    Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱採用 Werkzeug ,模板引擎则使用 Jinja2 ,使用 BSD 授权. Flask也被称为 " ...