Mock是什么?
在单元测试、模块的接口测试时,当这个模块需要依赖另外一个或几个类,而这时这些个类还没有开发好,这时我们就可以定义了Mock对象来模拟那些类的行为。
也就是自己实现一个假的依赖类,对这个类的方法你想要什么行为就可以有什么行为,你想让这个方法返回什么结果就可以返回怎么样的结果。
Gmock的特性:
轻松地创建mock类
支持丰富的匹配器(Matcher)和行为(Action)
支持有序、无序、部分有序的期望行为的定义
多平台的支持
使用流程:
引入你要用到的Google Mock名称. 除宏或其它特别提到的之外所有Google Mock名称都位于testing命名空间之下.
建立模拟对象(Mock Objects).
[设置模拟对象的默认动作].
在模拟对象上设置你的预期(它们怎样被调用,应该怎样回应?).
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的对象,上例中就是TestUser的一个对象。
Method是mock对象中的mock方法,它的参数可以通过matchers规则去匹配。
With是多个参数的匹配方式指定。
Times表示这个方法可以被执行多少次。
InSequence用于指定函数执行的顺序。它是通过同一序列中声明期待的顺序确定的。
After方法用于指定某个方法只能在另一个方法之后执行。
WillOnce表示执行一次方法时,将执行其参数action的方法。一般我们使用Return方法,用于指定一次调用的输出。
WillRepeatedly表示一直调用一个方法时,将执行其参数action的方法。需要注意下它和WillOnce的区别,WillOnce是一次,WillRepeatedly是一直。
RetiresOnSaturation用于保证期待调用不会被相同的函数的期待所覆盖
例如:
EXPECT_CALL(test_user,Pay(_)).Times(3).WillOnce(Return(true)).WillOnce(Return(true)).WillRepeatedly(Return(false));
调用test_user的Pay()方法
这个方法会调用3次
第1次被调用时返回true
第2次被调用时返回true
从第3次被调用返回false
如果想至少调用3次
Times(Atleaste(3));
Google Mock的使用
例子:
class User {
public:
virtual ~User(){ }
public:
virtual bool Login(const std::string& username, const std::string& password) = 0;
virtual bool Pay(int money) = 0;
virtual bool Online() = 0;
};
需要注意:
析构函数 必须是虚函数
方法也得定义为纯虚函数
class TestUser : public User {
public:
MOCK_METHOD2(Login, bool(const std::string&, const std::string&));
MOCK_METHOD1(Pay, bool(int));
MOCK_METHOD0(Online, bool());
};
Mock_METHOD#1(#2, #3(#4))
#1是要Mock的方法有几个参数
#2是要Mock的方法名称
#3是要Mock的方法的返回值
#4是要Mock的方法的具体参数
static void test4(){
TestUser test_user;
EXPECT_CALL(test_user, Online()).WillRepeatedly(Return(false));
EXPECT_CALL(test_user, Login(StrNe("admin"), _)).WillRepeatedly(Return(true));
EXPECT_CALL(test_user,Pay(_)).Times(3).WillOnce(Return(true)).WillOnce(Return(true)).WillRepeatedly(Return(false));
Biz biz;
biz.SetUser(&test_user);
string user_ret = biz.pay("user", "", 1);
cout << "test4 ret value: " << user_ret << endl;
user_ret = biz.pay("user", "", 1);
cout << "test4 ret value: " << user_ret << endl;
user_ret = biz.pay("user", "", 1);
cout << "test4 ret value: " << user_ret << endl;
}
更多理解,请参考文章:
http://blog.csdn.net/breaksoftware/article/details/51384083
http://www.cnblogs.com/welkinwalker/archive/2011/11/29/2267225.html