【问题标题】:How to test if a method from a base class has been called and executed using google mock?如何测试是否已使用 google mock 调用并执行了基类中的方法?
【发布时间】:2017-06-22 18:32:36
【问题描述】:

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

class BankAccount {

public:

    BankAccount();

    int withdraw(int balance, int withdrawalAmount);

};

在 BankAccount.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));
};

我的 MockBankAccount 类继承自 BankAccount 类。

在我的 test.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 类调用并执行了withdraw 方法(即执行了 BankAccount::withdraw)。当我运行测试时,它通过了,我希望withdraw 已被调用并执行,但是如果我在 BankAccount::withdraw 上放置一个断点并进行调试,我可以看到它实际上从未到达基类中的方法。有没有办法使用 Google Mock 来检查 BankAccount::withdraw,例如使用其他方法(组合而不是继承、模板等)?

【问题讨论】:

    标签: c++ unit-testing inheritance googletest googlemock


    【解决方案1】:

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

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

    但是让我们谈谈模拟。当测试的类依赖于其他类时,您只需要 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(),你不需要任何模拟。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-24
      • 1970-01-01
      • 1970-01-01
      • 2021-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多