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

使用EXPECT_CALL宏抛自定义异常编译失败,求正确代码方案

问题解决与修正代码

错误原因分析

  1. 类型捕获不匹配:测试用例抛出CustomException,但catch块捕获的是std::invalid_argument,既会导致异常无法被正确处理,也会在编译阶段引发fmt格式字符串的类型转换冲突。
  2. 模板推导歧义:原CustomException的构造函数模板未明确区分fmt格式字符串参数,导致GMock的Throw转发参数时,编译器无法正确推导fmt的格式字符串类型。

修正后的代码

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <stdexcept>
#include <fmt/core.h>

using ::testing::_;
using ::testing::Throw;

class CustomException : public std::exception
{
public:
    // 显式声明格式字符串类型,消除模板推导歧义
    template <typename... Args>
    explicit CustomException(fmt::format_string<Args...> fmt, Args&&... args)
        : _exception_string{fmt::format(fmt, std::forward<Args>(args)...) + _exception_suffix}
    {
    }

    inline const char* what() const noexcept override
    {
        return _exception_string.c_str();
    }

private:
    std::string _exception_suffix{" Custom exception..."};
    std::string _exception_string{};
};

class Calculator {
public:
    virtual double Divide(double a, double b) {
        if (b == 0.0) {
            throw std::invalid_argument("Division by zero");
        }
        return a / b;
    }
};

// Mock class for Calculator
class MockCalculator : public Calculator {
public:
    MOCK_METHOD(double, Divide, (double a, double b), (override));
};

TEST(CalculatorTest, DivideWithExceptions) {
    MockCalculator mockCalculator;

    EXPECT_CALL(mockCalculator, Divide(10.0, 0.0))
        .WillOnce(Throw(CustomException("Division by zero")));
    
    try {
        double result = mockCalculator.Divide(10.0, 0.0);
        FAIL() << "Expected exception not thrown.";
    } catch (const CustomException& e) {
        EXPECT_STREQ(e.what(), "Division by zero Custom exception...");
    } catch (...) {
        FAIL() << "Caught unexpected exception type.";
    }
}

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

关键修改点

  • 构造函数优化:将第一个参数显式指定为fmt::format_string<Args...>,明确告知编译器该参数为fmt格式字符串,解决模板推导的类型歧义问题。
  • 捕获类型修正:把catch块的捕获类型改为const CustomException&,确保能正确捕获自定义异常,同时添加兜底捕获块处理意外情况。
  • 验证逻辑更新:调整EXPECT_STREQ的预期值,匹配自定义异常拼接后的完整错误信息。

内容的提问来源于stack exchange,提问作者pankaj kushwaha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 20:40:15