当前位置: 首页 > 工具软件 > Google Mock > 使用案例 >

【Google mock(g_mock)学习记录】

阳福
2023-12-01

Google mock(g_mock)是什么

1.gmock是谷歌推出的开源白盒测试工具,用于编写C++模拟类的框架。通过gmock可以用一些简单的宏描述想要模拟的接口并指定其期望,在测试中有效地去除外部依赖,更方便地测试模块功能。对类里面需要打桩的函数mock.

2.在单元测试、模块的接口测试时,当这个模块需要依赖另外一个或几个类,而这时这些个类还没有开发好,这时我们就可以定义了Mock对象来模拟那些类的行为。也就是自己实现一个假的依赖类,对这个类的方法你想要什么行为就可以有什么行为,你想让这个方法返回什么结果就可以返回怎么样的结果。

Google mock 使用

使用Mock类的一般流程如下:

  • 1.引入你要用到的Google Mock名称. (除宏或其它特别提到的之外所有Google Mock名称都位于testing命名空间之下).
    using ::testing::Return;
    testing::InitGoogleTest(&argc,argv);
    return RUN_ALL_TESTS();
  • 2.建立模拟对象(Mock Objects)
    class MockFoo: public Foo{
    public:
        MOCK_METHOD0(count,int());
        MOCK_METHOD#1(#2, #3(#4)) 
        // #1表示你要mock的方法共有几个参数,#2是你要mock的方法名称,#3表示这个方法的返回值类型,#4是这个方法具体的参数
        //MOCK_METHODn(..., ...); //其中n表示参数的个数
        //MOCK_CONST_METHODn(..., ...); //const成员方法用这种

    }
MockFoo *mockFoo = new MockFoo();
  • 3.可选的,设置模拟对象的默认动作.
    EXPECT_CALL(MockFoo, getNum())
        .Times(3)    //! 期望被调两次
        .WillOnce(Return(3))   //! 第一次返回值为3
        .WillOnce(Return(6)); //! 第二次返回值为6
        .WillOnce(Return(5)); //! 第三次返回值为5

        基数用于Times()中来指定模拟函数将被调用多少次|
        AnyNumber() 函数可以被调用任意次.
        AtLeast(n) 预计至少调用n次.
        AtMost(n) 预计至多调用n次.
        Between(m, n) 预计调用次数在m和n(包括n)之间.
        Exactly(n) 或 n 预计精确调用n次. 特别是, 当n为0时,函数应该永远不被调用.
        Actions(行为)用于指定Mock类的方法所期望模拟的行为:比如返回什么样的值、对引用、指针赋上怎么样个值,等等。 值的返回
        Return() 让Mock方法返回一个void结果
        Return(value) 返回值value
        ReturnNull() 返回一个NULL指针
        ReturnRef(variable) 返回variable的引用.
        ReturnPointee(ptr) 返回一个指向ptr的指针
        Assign(&variable, value) 将value分配给variable
        DoAll(a1, a2, …, an) 每次发动时执行a1到an的所有动作.
        Invoke(f) 使用模拟函数的参数调用f, 这里的f可以是全局/静态函数或函数对象.
        Invoke(object_pointer,&class::method)
        使用模拟函数的参数调用object_pointer对象的mothod方法.
  • 4.在模拟对象上设置你的预期(它们怎样被调用,应该怎样回应?).
    EXPECT_EQ(bar->count(),3);
    EXPECT_EQ(bar->count(),6);
    EXPECT_EQ(bar->count(),5);

EXPECT_CALL(mock_object, method(matcher1, matcher2, …))
.With(multi_argument_matcher)
.Times(cardinality)
.InSequence(sequences)
.After(expectations)
.WillOnce(action)
.WillRepeatedly(action)
.RetiresOnSaturation();

  • EXPECT_CALL声明一个调用期待,就是我们期待这个对象的这个方法按什么样的逻辑去执行。
  • mock_object是我们mock的对象,上例中MockFoo就是TestUser的一个对象。
  • Method是mock对象中的mock方法,它的参数可以通过matchers规则去匹配。
  • With是多个参数的匹配方式指定。
  • Times表示这个方法可以被执行多少次。
  • InSequence用于指定函数执行的顺序。它是通过同一序列中声明期待的顺序确定的。
  • After方法用于指定某个方法只能在另一个方法之后执行。
  • WillOnce表示执行一次方法时,将执行其参数action的方法。一般我们使用Return方法,用于指定一次调用的输出。
  • WillRepeatedly表示一直调用一个方法时,将执行其参数action的方法。需要注意下它和WillOnce的区别,WillOnce是一次,WillRepeatedly是一直。
  • RetiresOnSaturation用于保证期待调用不会被相同的函数的期待所覆盖

Google test 使用

TEST(testsuiteName, testcaseName)
TEST宏是gtest最基本的使用单元,一个testsuitName可以包含多个不同的testcaseName。每个testsuiteName和testcaseName构成的TEST宏内部就是该测试样例的具体实现。
testcaseName和testsuiteName内部会经过转换,所以最好不要含有下划线,例如 case1,case1,case_1等,以避免不必要的麻烦

TEST(BarTest,mock_foo_in_bar){
	MockFoo *mockFoo = new MockFoo();
	Bar *bar = new Bar(mockFoo);
	EXPECT_CALL(*mockFoo,count())
		.Times(3)
		.WillOnce(Return(3))
		.WillOnce(Return(6))
		.WillOnce(Return(5));
	EXPECT_EQ(bar->count(),3);
	EXPECT_EQ(bar->count(),6);
	EXPECT_EQ(bar->count(),5);
	delete bar;
	delete mockFoo;
}

编译完gmock后吗,主要生成了一个静态库gmock_main.a。该库中包含了gmock的框架,同时,也包含了gtest框架,可以认为gtest是gmock的一个子集。在gmock_main.a中默认编译了一个main函数,该main函数会初始化gmock和gtest,并且执行所有的TEST或TEST_F宏定义的测试用例,所以使用gmock_main.a进行单元测试时,不能编写main函数,否则会出现多个main冲突。如果需要重写main函数,可以使用命令“make gmock.a”,重新编译,会生成文件gmock.a。那么此时你需要自己编写main函数和初始化gmock框架。

 类似资料: