Gmock 1.10中重载函数的无值匹配参数期望设置
问题描述
我有一个MyClass类,重载了两个*=运算符:一个接收MyClass对象引用,另一个接收double类型。我希望在参数化测试中mock这个类,只验证调用的是正确的重载方法,不关心传入的具体参数值。
原本的EXPECT_CALL因两个重载存在歧义无法正常使用:
EXPECT_CALL(mymock, multiplication_assignment_operator(_)) .Times(1) .WillOnce(Return(30));
我需要用特定类型的匹配器指定调用哪个重载,但不知道如何编写匹配器来忽略参数值(类似_的效果)。我们使用的是Gmock 1.10版本。
解决方案
针对mock类中重载的multiplication_assignment_operator方法,要消除歧义并忽略参数值,可以采用以下两种写法:
1. 匹配const MyNameSpace::MyClass&类型参数
写法1:显式指定Matcher类型
直接用Matcher<const MyNameSpace::MyClass&>(_)明确匹配该类型的任意参数:
EXPECT_CALL(mockMyClass, multiplication_assignment_operator(Matcher<const MyNameSpace::MyClass&>(_))) .Times(1) .WillOnce(Return(29));
写法2:使用A<T>()匹配器(更简洁)
Gmock 1.10支持A<T>()匹配器,它可以直接匹配任意T类型的参数,完美满足“只关心类型、忽略值”的需求:
EXPECT_CALL(mockMyClass, multiplication_assignment_operator(A<const MyNameSpace::MyClass&>())) .Times(1) .WillOnce(Return(29));
2. 匹配double类型参数
同理,针对double重载的处理方式一致:
写法1:显式Matcher类型
EXPECT_CALL(mockMyClass, multiplication_assignment_operator(Matcher<double>(_))) .Times(1) .WillOnce(Return(31));
写法2:A<T>()简洁写法
EXPECT_CALL(mockMyClass, multiplication_assignment_operator(A<double>())) .Times(1) .WillOnce(Return(31));
整合为参数化测试
如果要将两个测试用例整合为参数化测试,可以按以下步骤实现:
步骤1:定义参数化测试类
#include "gtest/gtest.h" #include "gmock/gmock.h" #include "MyClass_mock.hpp" #include "SUT_MyClass.hpp" using ::testing::Test; using ::testing::_; using ::testing::Return; using ::testing::A; // 定义测试参数:包含mock返回值、重载类型标记 enum class OverloadType { MyClassRef, Double }; struct TestParam { int mockReturnValue; OverloadType overloadType; }; class Test_SUT_MyClass_Param : public Test, public ::testing::WithParamInterface<TestParam> { protected: MyNameSpace::MockMyClass mockMyClass; virtual void SetUp() {} virtual void TearDown() {} };
步骤2:编写参数化测试逻辑
TEST_P(Test_SUT_MyClass_Param, verify_correct_overload_called) { const auto param = GetParam(); if (param.overloadType == OverloadType::MyClassRef) { EXPECT_CALL(mockMyClass, multiplication_assignment_operator(A<const MyNameSpace::MyClass&>())) .Times(1) .WillOnce(Return(param.mockReturnValue)); // 触发调用MyClass&重载的SUT方法 SUT_MyClass v1(MyNameSpace::MyClass(10)); SUT_MyClass v2(MyNameSpace::MyClass(3)); const int return_value = v1.multiply_and_assignment_values(v2); EXPECT_EQ(param.mockReturnValue, return_value); } else { EXPECT_CALL(mockMyClass, multiplication_assignment_operator(A<double>())) .Times(1) .WillOnce(Return(param.mockReturnValue)); // 触发调用double重载的SUT方法 SUT_MyClass v1(MyNameSpace::MyClass(10)); const double v2 = 3.0; const int return_value = v1.multiply_and_assignment_values_other_type(v2); EXPECT_EQ(param.mockReturnValue, return_value); } } // 定义测试参数集合 INSTANTIATE_TEST_SUITE_P( OverloadValidationTests, Test_SUT_MyClass_Param, ::testing::Values( TestParam{29, OverloadType::MyClassRef}, TestParam{31, OverloadType::Double} ) );
补充说明
A<T>()是Gmock专为消除重载歧义设计的匹配器,无需额外定义自定义匹配器,直接满足“只验证类型、忽略参数值”的需求。- 两种写法在功能上完全等价,可根据团队编码习惯选择。
内容的提问来源于stack exchange,提问作者Nemelis
相关产品推荐
相关产品推荐

