Gtest/Gmock探究(一)-- 经典示例代码
来源:互联网 发布:易语言整人源码大全 编辑:程序博客网 时间:2024/06/05 20:40
接下来几篇文档记录,打算探究一下Google C++的单元测试框架Gtest/Gmock.
· 先给出经典初识Gtest框架的代码(AccountMangerTest)
· 紧接着探究TEST宏原理
· 随着是Gmock的MOCK_METHODX系列宏的探究
代码结构:
首先,准备gmock的源代码(我这里是gmock-1.7.0),并且按照官方文档编译通过。
补充gmock的编译:
cd gmock-1.7.0
./configure && make
其次,将我们的代码文件夹命名为AccountManagerTest,与gmock-1.7.0在同一级目录(代码目录结构如上图所示)。下面列出我们的测试代码文件内容,以及编译和运行方法:
// Account.h#pragma once#include <string>using namespace std;class Account {private: string m_strAccountId; long m_nBalance;public: Account() : m_strAccountId(""), m_nBalance(0) {;} Account(const string &initAccountId, long initialBalance) : m_strAccountId(initAccountId), m_nBalance(initialBalance) {;} bool isNil() { return m_strAccountId == ""; } void debit(long amount) { m_nBalance -= amount; } void credit(long amount) { m_nBalance += amount; } long getBalance() const { return m_nBalance; } string getAccountId() const { return m_strAccountId; } void SetId(const string &id) { m_strAccountId = id; }};
// AccountManager.h#pragma once#include "Account.h"class AccountManager {public: virtual Account findAccountForUser(const string &userId) = 0; virtual void updateAccount(const Account &account) = 0;};
// AccountService.h#pragma once#include <string> using namespace std;#include "Account.h" #include "AccountManager.h" class AccountService { private: AccountManager* pAccountManager; public: AccountService(); void setAccountManager(AccountManager* pManager); bool withdraw(const string &id, long amount); void topup(const string &id, long amount); void transfer(const string& senderId, const string& beneficiaryId, long amount); };
// AccountService.cpp#include "AccountService.h"AccountService::AccountService() { pAccountManager = NULL;}void AccountService::setAccountManager(AccountManager *pManager) { pAccountManager = pManager;}void AccountService::transfer(const string &senderId, const string &beneficiaryId, long amount) { Account sender = pAccountManager->findAccountForUser(senderId); Account beneficiary = pAccountManager->findAccountForUser(beneficiaryId); sender.debit(amount); beneficiary.credit(amount); pAccountManager->updateAccount(sender); pAccountManager->updateAccount(beneficiary);}bool AccountService::withdraw(const string &id, long amount) { Account owner = pAccountManager->findAccountForUser(id); if (owner.isNil()) { return false; } owner.debit(amount); pAccountManager->updateAccount(owner); return true;}void AccountService::topup(const string &id, long amount) { Account owner = pAccountManager->findAccountForUser(id); if (owner.isNil()) { owner.SetId(id); } owner.credit(amount); pAccountManager->updateAccount(owner);}
// AccountHelper.h#include "Account.h"#include <map>using namespace std;class AccountHelper {private: map<string, Account> m_mapAccounts; // an internal map to store all Accounts for testpublic: AccountHelper(map<std::string, Account> &mAccount); AccountHelper() {;} void updateAccount(const Account &account); Account findAccountForUser(const std::string &userId);};
// AccountHelper.cpp#include "AccountHelper.h"AccountHelper::AccountHelper(std::map<std::string, Account> &mAccount) { m_mapAccounts = mAccount;}void AccountHelper::updateAccount(const Account &account) { m_mapAccounts[account.getAccountId()] = account;}Account AccountHelper::findAccountForUser(const std::string &userId) { if (m_mapAccounts.find(userId) != this->m_mapAccounts.end()) return this->m_mapAccounts[userId]; return Account();}
// MockAccountManager.h#include "AccountManager.h"#include "gtest/gtest.h"#include "gmock/gmock.h"class MockAccountManager : public AccountManager {public: MOCK_METHOD1(findAccountForUser, Account(const string&)); MOCK_METHOD1(updateAccount, void(const Account&));};
// main.cpp#include "AccountHelper.h"#include "MockAccountManager.h"#include "AccountService.h"TEST(AccountServiceTest, transferTest) { map<std::string, Account> mapAccounts; mapAccounts["A"] = Account("A", 3000); mapAccounts["B"] = Account("B", 2000); AccountHelper helper(mapAccounts); MockAccountManager *pManager = new MockAccountManager(); EXPECT_CALL(*pManager, findAccountForUser(testing::_)) .Times(2) .WillRepeatedly(testing::Invoke(&helper, &AccountHelper::findAccountForUser)); EXPECT_CALL(*pManager, updateAccount(testing::_)).WillRepeatedly( testing::Invoke(&helper, &AccountHelper::updateAccount)); AccountService as; as.setAccountManager(pManager); as.transfer("A", "B", 1005); EXPECT_EQ(1995, helper.findAccountForUser("A").getBalance()); EXPECT_EQ(3005, helper.findAccountForUser("B").getBalance()); delete pManager;}TEST(AccountServiceTest, topupTest) { AccountHelper helper; MockAccountManager *pManager = new MockAccountManager(); EXPECT_CALL(*pManager, findAccountForUser(testing::_)) .WillRepeatedly(testing::Invoke(&helper, &AccountHelper::findAccountForUser)); EXPECT_CALL(*pManager, findAccountForUser("B")) .WillRepeatedly(testing::Invoke(&helper, &AccountHelper::findAccountForUser)); EXPECT_CALL(*pManager, findAccountForUser("A")) .WillRepeatedly(testing::Return(Account("A", 5))); EXPECT_CALL(*pManager, updateAccount(testing::_)).WillRepeatedly( testing::Invoke(&helper, &AccountHelper::updateAccount)); AccountService as; as.setAccountManager(pManager); as.topup("B", 1005); as.topup("A", 5); EXPECT_EQ(10, helper.findAccountForUser("A").getBalance()); EXPECT_EQ(1005, helper.findAccountForUser("B").getBalance()); delete pManager;}int main(int argc, char **argv) { ::testing::InitGoogleMock(&argc, argv); return RUN_ALL_TESTS();}
# Makefile.linux# Makefile for Mr.H CSDN blog - Do a research on Gtest/Gmock 2017.12.14# Make command to use for dependenciesMAKE=makeRM=rmMKDIR=mkdir# Only "Debug" version for testCFG=Debug## Configuration: Debug#ifeq "$(CFG)" "Debug"OUTDIR=DebugOUTFILE=$(OUTDIR)/testCFG_INC=-I../gmock-1.7.0/include -I../gmock-1.7.0/gtest/include CFG_LIB=-lpthread -lc -lm -lrt -lgtest -lgmock -L ../gmock-1.7.0/lib/.libs \ -L ../gmock-1.7.0/gtest/lib/.libs CFG_OBJ=COMMON_OBJ=$(OUTDIR)/AccountHelper.o $(OUTDIR)/AccountService.o $(OUTDIR)/main.o OBJ=$(COMMON_OBJ) $(CFG_OBJ)ALL_OBJ=$(OUTDIR)/AccountHelper.o $(OUTDIR)/AccountService.o \ $(OUTDIR)/main.o -lpthread -lc -lm -lrt -lgtest -lgmock -L ../gmock-1.7.0/lib/.libs \ -L ../gmock-1.7.0/gtest/lib/.libs COMPILE=g++ -c -g -o "$(OUTDIR)/$(*F).o" $(CFG_INC) $<LINK=g++ -g -o "$(OUTFILE)" $(ALL_OBJ)# Pattern rules$(OUTDIR)/%.o : %.cpp $(COMPILE)# Build rulesall: $(OUTFILE)$(OUTFILE): $(OUTDIR) $(OBJ) $(LINK) -cp Debug/test ./$(OUTDIR): $(MKDIR) -p "$(OUTDIR)"# Rebuild this projectrebuild: cleanall all# Clean this projectclean: $(RM) -f $(OUTFILE) $(RM) -f $(OBJ)# Clean this project and all dependenciescleanall: cleanendif
说明:
这里只给出linux上的编译运行方式(代码使用标准STL库,所以Windows上也能运行,编译方法大家自己研究)
编译: make -f Makefile.linux
运行:./test
输出:
[==========] Running 2 tests from 1 test case.[----------] Global test environment set-up.[----------] 2 tests from AccountServiceTest[ RUN ] AccountServiceTest.transferTest[ OK ] AccountServiceTest.transferTest (0 ms)[ RUN ] AccountServiceTest.topupTest[ OK ] AccountServiceTest.topupTest (0 ms)[----------] 2 tests from AccountServiceTest (0 ms total)[----------] Global test environment tear-down[==========] 2 tests from 1 test case ran. (0 ms total)[ PASSED ] 2 tests.
阅读全文
0 0
- Gtest/Gmock探究(一)-- 经典示例代码
- Gtest/Gmock探究(二)--TEST宏分析
- GTest && GMock
- gtest和gmock
- gtest和gmock入门
- gtest与gmock学习
- GMock 与 GTest
- gtest入口代码示例
- Linux下安装gtest/gmock
- Linux下安装gtest/gmock
- gtest与gmock学习资料
- linux下gtest&gmock下载
- Hessian探究(一)Hessian入门示例
- Google Test(GTest)和Google Mock(GMock)入门简介
- 转:Linux下安装Gtest/Gmock
- Gtest和Gmock的安装使用
- gtest参数化测试代码示例
- gtest参数化测试代码示例
- 浅谈JAVA
- 打印杨辉三角
- Vue.js中,使用echarts
- Zabbix自动发现和自动注册
- 以太坊平台搭建
- Gtest/Gmock探究(一)-- 经典示例代码
- Android 的lowmemorykiller机制
- [翻译]理解/检测 Inline Hooks/ WinAPI Hooks (Ring3)
- 【转载】性能分析之看专业的,来进步
- 【动态规划】之硬币找零问题(难度:1星)
- 递归和非递归实现规律函数
- HDU
- android 4.4模拟器java代码设置隐藏drawableRight失败
- 原生js干货