用google mock模擬C++對象


google mock是用來配合google test對C++項目做單元測試的。它依賴於googletest(參見我上篇文章《如何用googletest寫單元測試》:?http://blog.csdn.net/russell_tao/article/details/7333226),下面我來說說linux上怎么用它來做單元測試。

本文包括:1、如何獲取、編譯google mock;2、如何使用gmock(下面用gmock來代稱google mock)配合gtest做單元測試。

 

1、如何獲取、編譯google mock

gmock的當前版本與gtest一樣,是1.6.0。可以從這個網址獲取:http://code.google.com/p/googlemock/downloads/list。

下載到壓縮包解壓后,下面我們開始編譯出靜態庫文件(必須得自己編譯出),以在我們自己的單元測試工程中使用。

與gtest相同,我們執行完https://blog.csdn.net/russell_tao/article/details/configure; make后,不能執行make install,理由與上篇相同。

驗證這個包有沒有問題,依然可以執行如下命令:

 

 
        


如果你看到類似下文的輸出屏幕,證明你的機器運行gmock沒有問題。

 

 

 
        


這時還沒有編譯出我們要的libgmock.a呢。繼續在gmock解包目錄下執行:

 

 

 
        


如此,當前目錄下會鏈接出我們需要的libgmock.a。注意,這個gmock.a靜態庫里,把gtest需要的gtest-all.cc都編譯進來了,所以我們的單元測試工程只需要鏈接libgmock,不再需要鏈接上文說的libgtest了。

 

 

2、如何使用gmock

首先,編譯我們自己的單元測試工程時,需要在makefile里加入以下編譯選項:-I${GTEST_DIR}/include -I${GMOCK_DIR}/include,這兩個目錄我們自己從上面的包里拷貝出來即可。鏈接時,需要加上libgmock.a。

 

還是以一個例子來說明怎么在mock對象的情況下寫單元測試。

 

我現在有一個生產者消費者網絡模型,消費者(例如client)會先發TCP請求到我的SERVER去訂閱某個對象。生產者(另一台SERVER)產生關於某個對象的事件后發給我的SERVER后,我的SERVER再把事件發給消費者。

就是這么簡單。

 

我現在想寫一個單元測試,主要測試代碼邏輯,不想去管網絡包的收發這些事情。

我現在有兩個類,一個叫CSubscriber,它封裝為一個訂閱的消費者,功能主要是操作網絡,包括網絡收發包,協議解析等。另一個叫CSubEventHandler,它主要做邏輯處理,去操作CSubscriber對象,例如epoll返回讀事件后,會構造一個CSubscriber對象,然后CSubEventHandler::handleRead方法就來處理這個CSubscriber對象。

 

我單元測試的目的是,測試CSubEventHandler::handleRead的業務邏輯,我同時也想測試CSubscriber方法里的協議解析邏輯,但是對於CSubscriber封裝的讀寫包部分,我希望可以mock成我想要的網絡包。

怎么做呢?

a)、先mock一個CSubscriber類如下:

 

 
        


其中,CSubscriber的構造方法必須有一個int型的fd,而readBuf和writeBuf都只接收一個int型的參數,而closeSock方法 沒有參數傳遞。於是我使用了MOCK_METHOD0和MOCK_METHOD1這兩個宏來聲明想MOCK的方法。這兩個宏的使用很簡單,解釋下:

 

MOCK_METHOD#1(#2, #3(#4) )

#2是你要mock的方法名稱!#1表示你要mock的方法共有幾個參數,#4是這個方法具體的參數,#3表示這個方法的返回值類型。

很簡單不是?!

 

b)、如果只關心mock方法的返回值。

這里用到一個宏ON_CALL。看例子:

 

 
        


什么意思呢?再用剛才的解釋方法:

 

ON_CALL(#1, #2(#3)).WillByDefault(Return(#4));

#1表示mock對象。就像我上面所說,對CSubscriber我定義了一個Mock類,那么就必須生成相應的mock對象,例如:

 

 
        


#2表示想定義的那個方法名稱。上例中我想定義readBuf這個方法的返回值。

 

#3表示readBuf方法的參數。這里的1000表示,只有調用CSubscriber::readBuf同時傳遞參數為1000時,才會用到ON_CALL的定義。

#4表示調用CSubscriber::readBuf同時傳遞參數為1000時,雅思怎么讀返回blen這個變量的值。

 

c)、如果還希望mock方法有固定的被調用方式

這里用到宏EXPECT_CALL,看個例子:

 

 
        


很相似吧?最后的Times表示,只希望readBuf在傳遞參數為1000時,被調用且僅被調用一次。

 

 

其實這些宏有很復雜的用法的,例如:

 

 
        


表示,readBuf希望被調用五次,第一次返回100,第二次返回150,后三次返回200。如果不滿足,會報錯。

 

 

d)、實際的調用測試

其實調用跟上篇googletest文章里的測試是一致的,我這里只列下上文的完整用例代碼(不包括被測試類的實現代碼):

 

 
        


CSubscriber的頭文件:

 

 

 
        



 

e)、main函數的寫法

與gtest相同,唯一的區別是初始化參數,如下:

 

 
        


如此,就可以完整的使用googletest/googlemock做C++工程的單元測試了,確實很簡單好用。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM