如何使用google mock测试和执行基类中的方法?

时间:2017-06-22 18:32:36

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

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

1 个答案:

答案 0 :(得分:0)

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

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

但是让我们谈谈Mocking。当测试类与其他类有依赖关系时,你只需要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)

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