如何让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
相关产品推荐
相关产品推荐

