【mockito】单元测试之mockito简单使用

摘要:
背景项目使用的是springmvc+mybatis开发;mock包为mockito-all;虽然也引用了powermock,但截至目前,还未使用到;如果使用到后续再补相关笔记。publicclassReportMediaDayMapperTest{@MockprivateReportMediaDayMapperreportMediaDayMapper;//定义了mybatis与数据库交互时,用到的接口@BeforepublicvoidsetUp()throwsException{MockitoAnnotations.initMocks;}@AfterpublicvoidtearDown()throwsException{}@TestpublicvoidgetAdvertiserAndMediaStatList()throwsException{MediaSearchModelsearchModel=newMediaSearchModel();Listlist=newArrayList();when.thenReturn;//mock一个场景,就是当请求getAdvertiserAndMediaStatList方法时,返回值为指定的list;Listlist2=reportMediaDayMapper.getAdvertiserAndMediaStatList;assertTrue;//断言list2为空,因为上面就是一个实例化并没有赋值,所以也是为空了。}对于DAO层,主要用到的是@Mock的使用。@BeforepublicvoidsetUp()throwsException{MockitoAnnotations.initMocks;}@AfterpublicvoidtearDown()throwsException{}至此,简单的mock测试就完了。mockito中有很多很多很多。常用的一些@spy、@mock、@injectMocks、以及Verify、whenthen、doreturn……

背景

项目使用的是springmvc+mybatis 开发;

mock包为mockito-all;虽然也引用了powermock,但截至目前,还未使用到;如果使用到后续再补相关笔记。

mock,个人理解,有两个场景比较常见吧。一个是在项目初期接口定义好后没有实现逻辑阶段;另一个就是针对已经有的逻辑自测阶段,而又不想(或者依赖的别人接口不想关心)被别人所左右的情况。

不管那种情况,都是一个目的:降低别人对自己的干扰。

大概从两个方面记录单测的mock:

dapper层:

dapper层,目前是给mybatis的定义接口层;这一层主要会结合mybatis.xml 与数据库进行交互;当开发阶段没有写完逻辑时,那就需要先来个“假实现”,这样不会影响团队中其他小伙伴的工作开展嘛。

public classReportMediaDayMapperTest {

    @Mock
    privateReportMediaDayMapper reportMediaDayMapper; // 定义了mybatis与数据库交互时,用到的接口

    @Before
    public void setUp() throwsException {
        MockitoAnnotations.initMocks(this);
    }

    @After
    public void tearDown() throwsException {

    }

    @Test
    public void getAdvertiserAndMediaStatList() throwsException {
        MediaSearchModel searchModel = newMediaSearchModel();
        List<AdvertiserAndMediaStatViewModel> list = new ArrayList<>();
        when(reportMediaDayMapper.getAdvertiserAndMediaStatList(searchModel)).thenReturn(list); // mock一个场景,就是当请求getAdvertiserAndMediaStatList方法时,返回值为指定的 list;
List<AdvertiserAndMediaStatViewModel> list2 =reportMediaDayMapper.getAdvertiserAndMediaStatList(searchModel); 
assertTrue(list2.isEmpty()); // 断言list2为空,因为上面就是一个实例化并没有赋值,所以也是为空了。
}

对于DAO层,主要用到的是 @Mock的使用。那么这个注解的作用究竟是什么呢?下面会结合另外一个一起总结。

service层:

主要mock对象一般就是对DAO层的依赖,另外就是别人的Service实现类;

@RunWith(MockitoJUnitRunner.class)
public classMediaServiceImplTest {

    @Mock
    privateReportMediaDayMapper mediaDayMapper; // mock 一个DAO层的接口

    @InjectMocks
    privateMediaServiceImpl mediaService; // Mock一个Service的实现类,为什么用@InjectMocks,一会儿说

    @Test
    public void getAdvertiserAndMediaStatList() throwsException {
        MediaSearchModel searchModel = newMediaSearchModel();
        List<AdvertiserAndMediaStatViewModel> list = new ArrayList<>();
        when(mediaDayMapper.getAdvertiserAndMediaStatList(searchModel)).thenReturn(list);

        list =mediaService.getAdvertiserAndMediaStatList(searchModel);

        assertTrue(list.isEmpty());
    }

其实,对于以上两个场景的mock,主要是围绕着@Mock、@InjectMocks进行玩的。那么他们分别代表什么意思呢?

官方文档上是这么描述的:

  • mock()/@Mock: create mockspy()/@Spy: partial mocking, real methods are invoked but still can be verified and stubbed
  • @InjectMocks: automatically inject mocks/spies fields annotated with@Spyor@Mock -- 这句话理解意思是它会把上下文中你标记为@Spy和@Mock的对象都自动注解进去。是不是就相当于把实现类中的私有成员属性(比如ReportMediaDayMapper的依赖)给偷梁换柱了
  • verify(): to check methods were called with given arguments
    • can use flexible argument matching, for example any expression via theany()
    • or capture what arguments where called using@Captorinstead

另外,就是你可能会注意到了@RunWith(MockitoJUnitRunner.class),其实也可以用另外一种方式(看↓)处理,就是初始化一些需要的东西。

@Before
    public void setUp() throwsException {
        MockitoAnnotations.initMocks(this); 
    }

    @After
    public void tearDown() throwsException {

    }

至此,简单的mock测试就完了。其实只是冰山一角。mockito中有很多很多很多。常用的一些@spy、@mock、@injectMocks、以及Verify、when then、doreturn ……

参考:

https://github.com/hehonghui/mockito-doc-zh

http://site.mockito.org/

http://static.javadoc.io/org.mockito/mockito-core/2.7.6/org/mockito/Mockito.html

免责声明:文章转载自《【mockito】单元测试之mockito简单使用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇VMware 安装 MacOS测试常用shell命令下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

pandas 几种获取dataframe列名的方式

1)通过columns字段获取,返回一个numpy类型的array print(df_data.columns.values) 2)通过list表列出 print(list(df_data)) 3)df.columns返回index,通过tolist()或者list(df.columns)转换为list类型 print(df_data.columns.to...

javascript语法--for in、for of和forEach

首先看简单for循环效果,功能最基本,但可以实现所有循环功能 for (let i = 0; i < list.length; i++) { } 接下来看for in、for of和forEach的常见用法 主要是侧重点不同 一、for in 重点打印key-value对 模板: for (const key in object) {...

使用filebeat 收集日志到logstash 收集日志redis再到logstash到es

大型场合的工作流程图 filebeat -->logstash ---> redis ---> logstash --->es 工作环境: 需要两台logstash, 安装jdk8 [root@es-web1]# apt install openjdk-8-jdk -y 这里已经安装filebeat 配置filebeat(这里的...

yarn 常用命令

yarn addyarn add [package]@[version]这将安装您的dependencies中的一个或多个包。用 --dev 或 -D 会在 devDependencies 里安装一个或多个包。 yarn global add <package...>全局安装依赖。对于绝大部分包来说,这是个坏习惯,因为它们是隐藏的。 最好本...

java 将MySql数据库中的数据(某一列)取出放入数组中 转

转:http://blog.csdn.net/ewili/article/details/8605638 假设mysql中test数据库中有个表式score,有数据,我只取第一列的数据出来: public void mysqlConnection(){ try { Class.forName("com.mysql.jdbc.Driver").new...

[转]敏捷开发中编写高质量Java代码

本文转自:http://dev.yesky.com/103/11164603.shtml 敏捷开发的理念已经流行了很长的时间,在敏捷开发中的开发迭代阶段中,我们可以通过五个步骤,来有效的提高整个项目的代码质量。 Java项目开发过程中,由于开发人员的经验、Java代码编写习惯,以及缺乏统一的标准和管理流程,往往导致整个项目的代码质量较差,难于维 护,需要...