zoukankan      html  css  js  c++  java
  • Mockito单测,mock service层的mapper

    转载: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

  • 相关阅读:
    react 样式继承 属性传递
    react css-in-js
    react 利用高阶组件给页面加上动画
    react路由过渡动画效果
    REACT列表过度
    react 过渡动画组件
    VueJs之计算属性
    VueJs之判断与循环
    VusJs之入门
    MYSQL之数据报表
  • 原文地址:https://www.cnblogs.com/ceshi2016/p/9546444.html
Copyright © 2011-2022 走看看