Mockcpp简介
- Mockcpp是一个面向C/C++的mock框架。
- 指定(或模拟)函数的行为,可以对入参进行校验,对出参进行设定,还可以指定函数的返回值。
- 它致力于:
- 尽量少的使用模版技术,以提高编译性能,降低错误信息的晦涩性;
- 框架产生的错误信息格式应该简单直观,信息应该全面,以帮助程序员更加快速的了解和定位问题;
- 生成一个mock对象应该尽可能的简单;
- 框架应该具备良好的扩展性,以应对各种特殊的需要;
- 能够支持针对静态函数的mock。
Mockcpp相关概念
mock规范
- 每个MOCKER(function)开始,跟一系列的.stubs、.with、.will等的内容的整体,称为一个mock规范。
核心关键字
- 指stubs、defaults、expects、before、with、after、will、then、id等这些直接跟在Mocker(function)/MOCK_METHOD(mocker, method)后面的关键字。
扩展关键字
- 指once()、eq()、check()、returnValue()、repeat()等这些作为核心关键字参数的关键字。
完整的mock规范示例
Mockcpp的七种约束
- 调用次数约束 -> expects()/stubs()
- 调用者选择器 -> caller()
- 先行调用约束 -> before()
- 调用参数约束 -> with()
- 后行调用约束 -> after()
- 调用行为约束 -> will()/then()
- 标识符指定 -> id()
调用次数约束
- 调用次数约束通过expects(times)指定。
- 如果不关心调用次数,则使用stubs()。
- 约束类型:
- 一次:once ()
- 准确次数:exactly (n)
- 至少:
- atLeast (n)
- atLeastOnce()
- 至多:
- 不调用:never ()
调用行为约束
- 函数调用行为通过will(behavior)/then(behavior)来指定。will()只能出现一次,但then()可以出现任意多次,且then()必须位于will()之后。
- 当使用will()/then()来指定函数调用行为时,指定的函数调用行为将会按照指定的顺序依次发生作用,如果指定的最后一个函数调用行为发生了作用之后,仍然有进一步的调用发生,如果其它约束条件都满足,则最后一个函数调用行为将持续发生作用。
- 约束类型:
- 返回一个值: returnValue (value)
- 返回一系列的值:returnObjectList (o1, o2,…)
- 抛出异常: throws (exception)
- 忽略返回值: ignoreReturnValue ()
- 转调一个stub函数:invoke(stubFunction)
- 重复返回一个值: repeat(value, times)
- 步增一个值:increase(from, to)/increase(from)】
- returnValue()用来指定匹配的调用所返回的单个值。如果它是指定最后一个函数调用行为,那么无论这个调用发生了多少次,指定的值总是作为返回值返回。如果它不是指定的最后一个函数调用行为,那么它仅仅返回一次指定的值。
- 在约束相同的情况下,如果希望一个调用每次返回的值是不相同的,那么使用returnObjectList()。 如果它是指定的最后一个函数调用行为,那么当最后一个对象返回后,如果匹配的调用再次发生,Mockcpp将会产生一个错误。另外,在当前的实现中,returnObjectList()的所允许指定对象个数是有限制的,这或许在某些情况下无法直接的满足测试的需求。这种情况下,你可以利用then()的无数量限制的特点来实现。
- 如果函数定义的返回值类型不是void ,则一定要指定函数调用行为。即使不关心返回值,也要通过ignoreReturnValue()来指定。
函数参数约束
- 调用参数约束通过with(contraint1, contraint2, …)指定。
- 在with()里,参数约束必须按照函数声明的参数顺序指定。
- 对于不需要指定约束的参数,可以通过any() 来忽略约束;最后一个有效约束后面的any()可以省略。
- 输入参数约束类型:
- 数值匹配:
- 相等:eq(value)
- 不等:neq(value)
- 大于:gt(value)
- 小于:lt(vlaue)
- 内存匹配:
- mirror(object)
- mirror(address, size)
- 对象内容监控:
- 引用传值 : outBound(object)
- 指针传值 : outBoundP(address)
- 字符串匹配:
-smirror(str)
- startWith(str)
- endWith(str)
- contains(str)
- 占位符:any()
- 输出参数约束类型:
- 通过引用得到输出参数:outBound (reference, 输入参数约束)
- 通过指针得到输出参数:outBoundP (pointer, 输入参数约束)
调用顺序约束:
- 调用顺序约束通过before()/after()指定。
- before()/after()可以在一个mock规范中指定多次,以满足复杂的调用序列要求。
- 调用顺序约束类型
- 之前:
- before (id)
- before (object, id)
- 之后:
- after (id)
- after (object, id)
标识符指定
- 当一个mock规范用到before()/after()等调用顺序约束时,需要给被参照的mock规范一个标识符。
- 标识符通过id(identity)指定,其中identity是一个字符串。
- 在一个对象范围内,identity必须唯一,否则Mockcpp则可能会引用到错误的调用描述。
Mockcpp校验
- 使用GlobalMockObject::verify()进行校验。
- verify之后,会自动执行reset。
- 如果是对象的mock,则应该使用mocker.verify()。