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

    转载:https://blog.csdn.net/dc_726/article/details/8568537

    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

  • 相关阅读:
    免费使用Adobe Flash Builder 4.6方法
    MySQL中concat函数
    PHP漏洞全解
    discuz 论坛 解决投票后不返回,提示AJAX错误的折中解决办法 common.js错误
    CoreSeek快速安装
    JSP基本语法
    『JAVA基础』使用JavaMail发邮件的实例 (转载)
    struts2过滤器和拦截器的区别
    【转】 myeclipse安装svn插件的多种方式
    用Java编写计算器的几种常见的做法
  • 原文地址:https://www.cnblogs.com/ceshi2016/p/9546453.html
Copyright © 2011-2022 走看看