zoukankan      html  css  js  c++  java
  • 强大的Mockito测试框架

    1自动生成Mock类


    在需要Mock的属性上标记@Mock注解,然后@RunWith(MockitoJUnitRunner.class)或者在setUp()方法中显示调用MockitoAnnotations.initMocks(this);生成Mock类即可。

    2自动注入Mock类到被测试类


    只要在被测试类上标记@InjectMocks,Mockito就会自动将标记@Mock、@Spy等注解的属性值注入到被测试类中。

    1. import static org.mockito.Mockito.when;  
    2.    
    3. import java.util.Collections;  
    4. import java.util.List;  
    5.    
    6. import javax.annotation.Resource;  
    7.    
    8. import org.junit.Assert;  
    9. import org.junit.Before;  
    10. import org.junit.Test;  
    11. import org.junit.runner.RunWith;  
    12. import org.mockito.InjectMocks;  
    13. import org.mockito.Mock;  
    14. import org.mockito.MockitoAnnotations;  
    15. importorg.springframework.test.context.ContextConfiguration;  
    16. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
    17.    
    18. import com.cdai.ssi.user.dao.UserDao;  
    19. import com.cdai.ssi.user.domain.UserDomain;  
    20. import com.cdai.ssi.user.dto.UserDto;  
    21. importcom.cdai.ssi.user.service.UserService;  
    22.    
    23. @RunWith(SpringJUnit4ClassRunner.class)  
    24. @ContextConfiguration({"classpath:spring/spring-config.xml"})  
    25. public class UserServiceTest {  
    26.           
    27.          @InjectMocks  
    28.          @Resource(name= "userService")  
    29.          privateUserService userService;  
    30.           
    31.          @Mock  
    32.          privateUserDao userDao;  
    33.    
    34.          @Before  
    35.          publicvoid setUp() {  
    36.                    MockitoAnnotations.initMocks(this);  
    37.          }  
    38.           
    39.          @Test  
    40.          publicvoid testQueryAll() {  
    41.                    when(userDao.selectAll()).  
    42.                             thenReturn(Collections.<UserDomain>emptyList());  
    43.                     
    44.                    List<UserDto>dtoList = userService.queryAll();  
    45.                     
    46.                    Assert.assertTrue(dtoList.isEmpty());  
    47.          }  
    48.           
    49. }  

    @InjectMocks的问题是:如果被测试类是代理类,那么注入会失效。比如上面的UserService如果是事务或者其他AOP代理类,那么进入@Test方法时UserService中的DAO属性不会被Mock类替换。

    3 Mock方法定制再也不用录制、播放了


    Mockito的Mock方法定制可读性很强,而且也不需要像EasyMock那样录制播放,定制后就可以使用。

    例如:

    when(userDao.selectAll()).

                       thenReturn(Collections.<UserDomain>emptyList());


    4有些方法想Mock定制,有些想调用真实方法


    因为@Mock针对接口生成Mock类,所以我们是没法调用到真实的实现类的方法。可以使用@Spy注解标注属性,并且标注@Resource注解让spring注入真实实现类,那么Mockito就会自动生成Spy类。

    例如:

    @InjectMocks

    @Resource(name ="userService")

    privateUserService userService;

            

    @Spy

    @Resource

    privateUserDao userDao;

    Spy类就可以满足我们的要求。如果一个方法定制了返回值或者异常,那么就会按照定制的方式被调用执行;如果一个方法没被定制,那么调用的就是真实类的方法。

    如果我们定制了一个方法A后,再下一个测试方法中又想调用真实方法,那么只需在方法A被调用前,调用Mockito.reset(spyObject);就行了。

    1. import static org.mockito.Mockito.when;  
    2.    
    3. import org.mockito.Mockito;  
    4.    
    5. public class TestMockObject implementsITestMock {  
    6.    
    7.          publicstatic void main(String[] args) {  
    8.                     
    9.                    ITestMockmock = Mockito.mock(TestMockObject.class);  
    10.                    System.out.println(mock.test1());  
    11.                    System.out.println(mock.test2());  
    12.                     
    13.                    ITestMockspy = Mockito.spy(new TestMockObject());  
    14.                    System.out.println(spy.test1());  
    15.                    System.out.println(spy.test2());  
    16.                     
    17.                    when(spy.test1()).thenReturn(100);  
    18.                    System.out.println(spy.test1());  
    19.                     
    20.                    Mockito.reset(spy);  
    21.                    System.out.println(spy.test1());  
    22.                    System.out.println(spy.test2());  
    23.                     
    24.                    when(spy.test1()).thenReturn(104);  
    25.                    System.out.println(spy.test1());  
    26.          }  
    27.    
    28.          @Override  
    29.          publicint test1() {  
    30.                    System.out.print("RealTest1()!!! - ");  
    31.                    return1;  
    32.          }  
    33.    
    34.          @Override  
    35.          publicint test2() {  
    36.                    System.out.print("RealTest2()!!! - ");  
    37.                    return2;  
    38.          }  
    39.    
    40. }  

    输出为:

    0

    0

    Real Test1()!!! - 1

    Real Test2()!!! - 2

    Real Test1()!!! - 100

    Real Test1()!!! - 1

    Real Test2()!!! - 2

    Real Test1()!!! - 104

    要注意的是,对Spy对象的方法定制有时需要用另一种方法:

    ===============================================================================

    Importantgotcha on spying real objects!

    Sometimes it's impossible to usewhen(Object) for stubbing spies. Example:

      List list = new LinkedList();

      List spy = spy(list);

      

      //Impossible: real method is called so spy.get(0) throwsIndexOutOfBoundsException (the list is yet empty)

      when(spy.get(0)).thenReturn("foo");

      

      //You have to use doReturn() for stubbing

      doReturn("foo").when(spy).get(0);

    ===============================================================================

    因为用when(spy.f1())会导致f1()方法被真正执行,所以就需要另一种写法。


    参考资料

    Mockito文档

    http://mockito.googlecode.com/svn/branches/1.6/javadoc/org/mockito/Mockito.html

  • 相关阅读:
    最新屏蔽微信举报方法
    C# WIN 生成机器码
    Quartz.net的快速简单上手使用以及防止IIS回收停止Job的处理
    MVC、Web API 请求接口报错“自定义错误模块不能识别此错误。”解决
    获取微信短链接的官方接口
    Window 通过cmd查看端口占用、相应进程、杀死进程
    微信域名检测、防封,微信跳转技术揭秘(二) -- 微信跳转揭秘
    微信域名检测、防封,微信跳转技术揭秘(一) -- 域名检测原理及防封方案
    各种比较方便给力的小工具
    《Git学习指南》学习笔记(三)
  • 原文地址:https://www.cnblogs.com/zhaoxinshanwei/p/6274145.html
Copyright © 2011-2022 走看看