轻松编写c++单元测试

发表于:2013-8-28 11:06

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:RickyChan0623    来源:51Testing软件测试网采编

  清单 8. 待测试的程序逻辑

// Account.h
// basic application data class
#pragma once
#include <string>
class Account
{
private:
std::string accountId;
long balance;
public:
Account();
Account(const std::string& accountId, long initialBalance);
void debit(long amount);
void credit(long amount);
long getBalance() const;
std::string getAccountId() const;
};
// Account.cpp
#include "Account.h"
Account::Account()
{
}
Account::Account(const std::string& accountId, long initialBalance)
{
this->accountId = accountId;
this->balance = initialBalance;
}
void Account::debit(long amount)
{
this->balance -= amount;
}
void Account::credit(long amount)
{
this->balance += amount;
}
long Account::getBalance() const
{
return this->balance;
}
std::string Account::getAccountId() const
{
return accountId;
}
// AccountManager.h
// the interface of external services which should be mocked
#pragma once
#include <string>
#include "Account.h"
class AccountManager
{
public:
virtual Account findAccountForUser(const std::string& userId) = 0;
virtual void updateAccount(const Account& account) = 0;
};
// AccountService.h
// the class to be tested
#pragma once
#include <string>
#include "Account.h"
#include "AccountManager.h"
class AccountService
{
private:
AccountManager* pAccountManager;
public:
AccountService();
void setAccountManager(AccountManager* pManager);
void transfer(const std::string& senderId,
const std::string& beneficiaryId, long amount);
};
// AccountService.cpp
#include "AccountService.h"
AccountService::AccountService()
{
this->pAccountManager = NULL;
}
void AccountService::setAccountManager(AccountManager* pManager)
{
this->pAccountManager = pManager;
}
void AccountService::transfer(const std::string& senderId,
const std::string& beneficiaryId, long amount)
{
Account sender = this->pAccountManager->findAccountForUser(senderId);
Account beneficiary = this->pAccountManager->findAccountForUser(beneficiaryId);
sender.debit(amount);
beneficiary.credit(amount);
this->pAccountManager->updateAccount(sender);
this->pAccountManager->updateAccount(beneficiary);
}

  清单 9. 相应的单元测试

// AccountServiceTest.cpp
// code to test AccountService
#include <map>
#include <string>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "../Account.h"
#include "../AccountService.h"
#include "../AccountManager.h"
// MockAccountManager, mock AccountManager with googlemock
class MockAccountManager : public AccountManager
{
public:
MOCK_METHOD1(findAccountForUser, Account(const std::string&));
MOCK_METHOD1(updateAccount, void(const Account&));
};
// A facility class acts as an external DB
class AccountHelper
{
private:
std::map<std::string, Account> mAccount;
// an internal map to store all Accounts for test
public:
AccountHelper(std::map<std::string, Account>& mAccount);
void updateAccount(const Account& account);
Account findAccountForUser(const std::string& userId);
};
AccountHelper::AccountHelper(std::map<std::string, Account>& mAccount)
{
this->mAccount = mAccount;
}
void AccountHelper::updateAccount(const Account& account)
{
this->mAccount[account.getAccountId()] = account;
}
Account AccountHelper::findAccountForUser(const std::string& userId)
{
if (this->mAccount.find(userId) != this->mAccount.end())
return this->mAccount[userId];
else
return Account();
}
// Test case to test AccountService
TEST(AccountServiceTest, transferTest)
{
std::map<std::string, Account> mAccount;
mAccount["A"] = Account("A", 3000);
mAccount["B"] = Account("B", 2000);
AccountHelper helper(mAccount);
MockAccountManager* pManager = new MockAccountManager();
// specify the behavior of MockAccountManager
// always invoke AccountHelper::findAccountForUser
// when AccountManager::findAccountForUser is invoked
EXPECT_CALL(*pManager, findAccountForUser(testing::_)).WillRepeatedly(
testing::Invoke(&helper, &AccountHelper::findAccountForUser));
// always invoke AccountHelper::updateAccount
//when AccountManager::updateAccount is invoked
EXPECT_CALL(*pManager, updateAccount(testing::_)).WillRepeatedly(
testing::Invoke(&helper, &AccountHelper::updateAccount));
AccountService as;
// inject the MockAccountManager object into AccountService
as.setAccountManager(pManager);
// operate AccountService
as.transfer("A", "B", 1005);
// check the balance of Account("A") and Account("B") to
//verify that AccountService has done the right job
EXPECT_EQ(1995, helper.findAccountForUser("A").getBalance());
EXPECT_EQ(3005, helper.findAccountForUser("B").getBalance());
delete pManager;
}
// Main.cpp
#include <gtest/gtest.h>
#include <gmock/gmock.h>
int main(int argc, char** argv) {
testing::InitGoogleMock(&argc, argv);
// Runs all tests using Google Test.
return RUN_ALL_TESTS();
}

54/5<12345>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号