前提:pom引用
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.0.5.RELEASE</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-all</artifactId>
    <version>1.10.19</version>
</dependency>
背景:
方便后台开发自测接口,去除对象之间的复杂依赖,关注代码逻辑的正确性。
原理:
Mockito就是用Java提供的Dynamic Proxy API来实现的。
以下是简单的小demo:
package com.mock;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
/**
 * 所以测试类的基类
 *
 * @author tom_plus
 * @date 2017-01-02-17:20
 */
@ContextConfiguration(locations = {"classpath:applicationContext-test.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners(listeners = {DependencyInjectionTestExecutionListener.class,
        TransactionalTestExecutionListener.class})
public class AbstractServiceIT {
}
package com.mock.demo;
import com.AopTargetUtils;
import com.mock.AbstractServiceIT;
import com.springapp.bean.Teacher;
import com.springapp.service.TeacherService;
import com.springapp.service.TestService;
import com.springapp.utils.SessionContext;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.transaction.annotation.Transactional;
import org.testng.Assert;
import java.util.List;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
/**
 * mock 使用demo
 * 一个强大的用于 Java 开发的模拟测试框架
 *
 * @author tom_plus
 * @date 2017-01-02-17:45
 */
public class MockServiceIT extends AbstractServiceIT{
    @Mock
    SessionContext sessionContext;
    @Autowired
    private TestService testService;
    @Before
    public void befTest() {
        MockitoAnnotations.initMocks(this);
        when(sessionContext.getId()).thenReturn(3);
        try {
            ReflectionTestUtils.setField(AopTargetUtils.getTarget(testService), "sessionContext", sessionContext);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Test
    @Transactional
    public void updateIT() throws Exception {
        Teacher teacher = new Teacher();
        teacher.settName("樱木花道");
        int j = testService.update2(teacher);
        System.out.println("result:"+j);
        Assert.assertEquals(j,1,"更新成功");
    }
    /**
     * 参数匹配器,一旦使用参数匹配器,则方法中必须处处使用参数匹配器
     */
    @Test
    public void argumentMatcherTest(){
        List<String> list = mock(List.class);
        when(list.get(anyInt())).thenReturn("hello","world");
        String result = list.get(0)+list.get(1);
        System.out.println(result);
        //verify 方法验证mock 对象的互动次数
        verify(list,times(2)).get(anyInt());
        verify(list,atLeast(2)).get(anyInt());
        Assert.assertEquals("helloworld", result);
    }
    /**
     * 使用异常处理void 方法
     */
    @Test
    public void stubbingForVoidMethod() {
        List<String> list = mock(List.class);
        doThrow(new RuntimeException("you are clear a list!")).when(list).clear();
        list.clear();
    }
}
package com;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.support.AopUtils;
import java.lang.reflect.Field;
/**
 * Created by tom_plus on 2017/1/2.
 */
public class AopTargetUtils {
    /**
     * 获取 目标对象
     *
     * @param proxy 代理对象
     * @throws Exception 默认spring中Service对象是代理对象,不能直接把值设置到属性上,所以我们自己写个小的工具类
     */
    public static Object getTarget(Object proxy) throws Exception {
        if (!AopUtils.isAopProxy(proxy)) {
            return proxy;//不是代理对象
        }
        //jdk
        if (AopUtils.isJdkDynamicProxy(proxy)) {
            return getJdkDynamicProxyTargetObject(proxy);
        } else { //cglib
            return getCglibProxyTargetObject(proxy);
        }
    }
    private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
        Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");//获得字节码文件中的MethodInterceptor cglib$CALLBACK_0 变量
        h.setAccessible(true);
        Object dynamicAdvisedInterceptor = h.get(proxy);
        Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
        advised.setAccessible(true);
        Object target = ((AdvisedSupport) advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
        return target;
    }
    private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
        Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
        h.setAccessible(true);
        AopProxy aopProxy = (AopProxy) h.get(proxy);
        Field advised = aopProxy.getClass().getDeclaredField("advised");
        advised.setAccessible(true);
        Object target = ((AdvisedSupport) advised.get(aopProxy)).getTargetSource().getTarget();
        return target;
    }
}