You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 04:35:10