Mockcpp简介

时间:2024-03-30 21:48:09

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简介

Mockcpp的七种约束

  • 调用次数约束 -> expects()/stubs()
  • 调用者选择器 -> caller()
  • 先行调用约束 -> before()
  • 调用参数约束 -> with()
  • 后行调用约束 -> after()
  • 调用行为约束 -> will()/then()
  • 标识符指定 -> id()

调用次数约束

  • 调用次数约束通过expects(times)指定。
  • 如果不关心调用次数,则使用stubs()。
  • 约束类型:
    • 一次:once ()
    • 准确次数:exactly (n)
    • 至少:
      • atLeast (n)
      • atLeastOnce()
    • 至多:
      • atMost (n)
      • atMostOnce()
    • 不调用: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)
    • 对象内容监控:
      • spy(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()。