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

如何让GMock对象返回固定std::forward_list?编译报错求助

问题:Google Mock编译错误——返回值类型不匹配

我编写了如下单元测试代码:

TEST(AccountServiceShould, print_a_statement_containing_all_transactions) {
    auto transactionRepository = new TransactionRepositoryMock;
    std::forward_list<model::Transaction *> transactionList;
    auto statementPrinter = new StatementPrinterMock;

    transactionList.assign({transaction("22/12/2019", 1000)});

    ON_CALL(
            *transactionRepository,
            all()
    )
            .WillByDefault(Return(transactionList));

    Clock *myClock = new Clock;

    auto accountService = new AccountService(transactionRepository, myClock);

    EXPECT_CALL(*statementPrinter, print(Eq(transactionList)));

    accountService->printStatement();

    delete accountService;
    delete transactionRepository;
    delete myClock;
    delete statementPrinter;
}

编译时出现如下错误:

No viable conversion from 'internal::ReturnAction<forward_list<Transaction *, allocator<Transaction *>>>' to 'const Action<std::forward_list<model::Transaction, std::allocator<model::Transaction>> ()>' 
candidate template ignored: requirement 'internal::disjunction<std::is_constructible<std::function<std::forward_list<model::Transaction, std::allocator<model::Transaction>> ()>, testing::internal::ReturnAction<std::forward_list<model::T... 
candidate template ignored: could not match 'Action' against 'ReturnAction' 
explicit constructor is not a candidate 
candidate template ignored: could not match 'OnceAction' against 'Action' 
candidate template ignored: requirement 'conjunction<testing::internal::negation<std::is_same<void, std::forward_list<model::Transaction, std::allocator<model::Transaction>>>>, testing::internal::negation<std::is_reference<std::forward_... 
passing argument to parameter 'action' here

尝试修改transactionList类型、使用动态对象甚至自定义MATCHER_P都无法解决,求帮助!


错误原因分析

核心问题是类型不匹配:

  • 你的TransactionRepositoryMock::all()方法的返回类型被定义为std::forward_list<model::Transaction>(对象列表)
  • 但你实际传入的transactionList是std::forward_list<model::Transaction*>(指针列表)
    Google Mock无法在这两种不兼容的类型之间完成转换,因此抛出编译错误。

解决方案

1. 对齐mock方法与变量的类型

先确认TransactionRepositoryMock中all()的签名,根据不同的定义调整代码:

  • 如果mock定义为返回对象列表:

    class TransactionRepositoryMock : public TransactionRepository {
    public:
        MOCK_METHOD(std::forward_list<model::Transaction>, all, (), (override));
    };
    

    则修改transactionList类型为对象列表:

    std::forward_list<model::Transaction> transactionList;
    transactionList.assign({model::Transaction("22/12/2019", 1000)});
    
  • 如果mock定义为返回指针列表:

    class TransactionRepositoryMock : public TransactionRepository {
    public:
        MOCK_METHOD(std::forward_list<model::Transaction*>, all, (), (override));
    };
    

    则确保transactionList的元素为有效指针(注意后续清理避免内存泄漏):

    std::forward_list<model::Transaction*> transactionList;
    transactionList.assign({new model::Transaction("22/12/2019", 1000)});
    

2. 修正EXPECT_CALL的参数类型

确保EXPECT_CALL中print方法的参数类型,与StatementPrinterMock::print的定义、transactionList类型完全一致。

3. 优化内存管理(可选)

避免手动delete导致的内存泄漏或错误,建议使用智能指针:

TEST(AccountServiceShould, print_a_statement_containing_all_transactions) {
    auto transactionRepository = std::make_unique<TransactionRepositoryMock>();
    std::forward_list<model::Transaction> transactionList;
    auto statementPrinter = std::make_unique<StatementPrinterMock>();

    transactionList.assign({model::Transaction("22/12/2019", 1000)});

    ON_CALL(*transactionRepository, all())
        .WillByDefault(Return(transactionList));

    auto myClock = std::make_unique<Clock>();
    auto accountService = std::make_unique<AccountService>(transactionRepository.get(), myClock.get());

    EXPECT_CALL(*statementPrinter, print(Eq(transactionList)));

    accountService->printStatement();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:25:08