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等注解的属性值注入到被测试类中。

    import static org.mockito.Mockito.when;
     
    import java.util.Collections;
    import java.util.List;
     
    import javax.annotation.Resource;
     
    import org.junit.Assert;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.mockito.InjectMocks;
    import org.mockito.Mock;
    import org.mockito.MockitoAnnotations;
    importorg.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
     
    import com.cdai.ssi.user.dao.UserDao;
    import com.cdai.ssi.user.domain.UserDomain;
    import com.cdai.ssi.user.dto.UserDto;
    importcom.cdai.ssi.user.service.UserService;
     
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration({"classpath:spring/spring-config.xml"})
    public class UserServiceTest {
            
             @InjectMocks
             @Resource(name= "userService")
             privateUserService userService;
            
             @Mock
             privateUserDao userDao;
     
             @Before
             publicvoid setUp() {
                       MockitoAnnotations.initMocks(this);
             }
            
             @Test
             publicvoid testQueryAll() {
                       when(userDao.selectAll()).
                                thenReturn(Collections.<UserDomain>emptyList());
                      
                       List<UserDto>dtoList = userService.queryAll();
                      
                       Assert.assertTrue(dtoList.isEmpty());
             }
            
    }

    @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);就行了。

    import static org.mockito.Mockito.when;
     
    import org.mockito.Mockito;
     
    public class TestMockObject implementsITestMock {
     
             publicstatic void main(String[] args) {
                      
                       ITestMockmock = Mockito.mock(TestMockObject.class);
                       System.out.println(mock.test1());
                       System.out.println(mock.test2());
                      
                       ITestMockspy = Mockito.spy(new TestMockObject());
                       System.out.println(spy.test1());
                       System.out.println(spy.test2());
                      
                       when(spy.test1()).thenReturn(100);
                       System.out.println(spy.test1());
                      
                       Mockito.reset(spy);
                       System.out.println(spy.test1());
                       System.out.println(spy.test2());
                      
                       when(spy.test1()).thenReturn(104);
                       System.out.println(spy.test1());
             }
     
             @Override
             publicint test1() {
                       System.out.print("RealTest1()!!! - ");
                       return1;
             }
     
             @Override
             publicint test2() {
                       System.out.print("RealTest2()!!! - ");
                       return2;
             }
     
    }

    输出为:

    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


  • 相关阅读:
    图片上传-下载-删除等图片管理的若干经验总结3-单一业务场景的完整解决方案
    图片上传-下载-删除等图片管理的若干经验总结2
    HDU 1195 Open the Lock
    HDU 1690 Bus System
    HDU 2647 Reward
    HDU 2680 Choose the best route
    HDU 1596 find the safest road
    POJ 1904 King's Quest
    CDOJ 889 Battle for Silver
    CDOJ 888 Absurdistan Roads
  • 原文地址:https://www.cnblogs.com/xiaomaohai/p/6157778.html
Copyright © 2011-2022 走看看