博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
强大的Mockito测试框架
阅读量:6656 次
发布时间:2019-06-25

本文共 3614 字,大约阅读时间需要 12 分钟。

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

你可能感兴趣的文章
【转载】MySQL 之临时表和内存表
查看>>
【原创】MySQL 之 slow log
查看>>
Linux基础 文本处理命令
查看>>
Flutter入门一:安装Windows开发环境
查看>>
MySQL Replication可扩展设计
查看>>
oracle 对象管理 05_系统函数
查看>>
Linux下Java运行环境安装
查看>>
lua 随机生成 中国大陆 ip
查看>>
三种实现页面跳转的方法
查看>>
Fuchsia 操作系统的四层结构
查看>>
Linux 4.21包含对AMD Rome处理器中新的Zen 2架构重要的新优化
查看>>
Linux内核的缓存
查看>>
react-jianshu项目的创建
查看>>
NSCalendar取得上个月
查看>>
echarts 2.0 macarons主题安装
查看>>
OpenStack块存储nova-volume工作机制和相关问题
查看>>
【C#每日一贴】禁用承载进程----“工程名.vshost.exe”
查看>>
ThinkPHP Where 条件中使用表达式
查看>>
wxpython
查看>>
matlab常用快捷键
查看>>