如何测试基类中的方法是否已使用谷歌模拟调用和执行?

How to test if a method from a base class has been called and executed using google mock?

本文关键字:谷歌 模拟 调用 执行 是否 方法 何测试 测试 基类      更新时间:2023-10-16

我正在尝试测试基类中的方法是否已使用Google Mock测试调用和执行。我有一个简单的银行账户类,它实现了函数撤回。在 BankAccount.h 文件中:

class BankAccount {
public:
BankAccount();
int withdraw(int balance, int withdrawalAmount);
};

在"银行帐户.cpp"文件中:

#include "BankAccount.h"
BankAccount::BankAccount()
{
}
int BankAccount::withdraw(int balance, int withdrawalAmount)
{
if (withdrawalAmount <= balance)
{
balance -= withdrawalAmount;
}
return balance;
}

在test.h文件中,我有:

#include "BankAccount.h"
class MockBankAccount : public BankAccount {
public:
MockBankAccount();
MOCK_METHOD2(withdraw, int(int balance, int withdrawalAmount));
};

我的模拟银行账户类继承自银行账户类。

在我的测试中.cpp文件:

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "test.h"
using namespace testing;
// Constructors/Destructors
MockBankAccount::MockBankAccount()
{
}
TEST(WithdrawAccountTest, Withdraw)
{
MockBankAccount mockAccount;
EXPECT_CALL(mockAccount, withdraw(5, 1))
.Times(1);
mockAccount.withdraw(5, 1);
}
// Main
int main(int argc, char* argv[])
{
InitGoogleTest(&argc, argv);
InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}

我想检查提款方法是否从 BankAccount 类调用和执行(即 BankAccount::withdrawal 被执行)。当我运行测试时,它通过了,我希望 withdrawal 已被调用和执行,但是如果我在 BankAccount::withdrawal 和调试上放置断点,我可以看到它从未真正到达基类的方法。有没有办法使用谷歌模拟来检查银行账户::提款,例如使用另一种方法(组合而不是继承、模板等)?

我想试着给你一个可以接受的答案。

首先,代码做了它应该做的事情。您在测试中调用"模拟方法",当然测试通过。但是测试永远不会调用基类的方法(这是正确的)。顺便说一下,测试是否调用了一个方法,然后直接调用这个方法是没有意义的。

但是让我们谈谈嘲笑。当测试的类依赖于其他类时,您只需要 Mocks。
考虑一个类Person,它依赖于BankAccount类,并且您希望测试类Person。测试时,隔离测试对象非常重要。这就是为什么你不想要,PersonBankAccount类中的真实实例交谈。嘲讽来了...

想象一下,除了你的类之外,还有类 Person:

class Person {
public:
Person(BankAccount *account, int balance) : ba(account), balance(balance) {}
int getMoneyfromBankAccount(int withdrawalAmount) {
ba->withdraw(balance, withdrawalAmount);
}
private:
BankAccount *ba;
int balance;
}

测试更改为:

TEST(PersonTest, testWhenPersonGetsMoneyFromTheBankAccount_withdrawIsCalled)
{
MockBankAccount mockAccount;
EXPECT_CALL(mockAccount, withdraw(5, 1))
.Times(1);
Person p(&mockAccount, 5);
p.getMoneyfromBankAccount(1);
}

并且不要忘记使银行帐户方法虚拟:

virtual int BankAccount::withdraw(int balance, int withdrawalAmount)

毕竟,如果您只想从类BankAccount中测试方法withdraw(),则不需要任何模拟。