用gtest測試類的私有成員

2022-03-06 08:56:11 字數 1392 閱讀 8725

使用gtest、或者cppunit之類的框架編寫單元測試**,乙個最常見的問題是對類私有成員的測試與驗證。理想情況下,我們希望在測試中,類中所有的資料與方法都是可以訪問的;而在產品**中,只暴露實現定義好的介面。

gtest官方文件中,也提到了對私有成員的處理,方法不外乎兩種:一是使用friend關鍵字,騙取信任得以通行;二是重構採用pimpl模式,公共類中只暴露介面,而實現類中暴露所有細節(public),測試時包含實現類即可。

但這兩個方法都試了一下,覺不太方便。

其實我們想要達到的目的無非是:在產品**中,該pubic的是public,該private的還是private;而在測試**中,全部都是public。於是:

#ifdef gtest

#define private public

#define protected public

#endif

將其放在每個類的宣告前,或者放在乙個單獨的標頭檔案如forcepublic.h中幷包含之。這樣,在編譯測試**時,加上gtest的預編譯巨集,就可以非常方便的使用被測試類中的任何成員了,並不會對產品**產生任何的影響。

如果你是以純源**的方式使用你的產品類的,這個方法沒有任何問題;但如果你是通過靜態庫,或者動態庫的方式使用你的產品類的,在測試**中若直接使用這些庫,編譯是沒有問題,因為全偽裝成了public,但在鏈結的時候,因為private的成員是沒有從庫中匯出來的,必然會出現鏈結錯誤。此時有兩個方案:一是以gtest的方式重新編譯庫;二是直接將產品源**編譯進你的測試工程中去。

#ifdef txnmgr_exports

#define txnmgr_api __declspec(dllexport)

#else

#ifdef gtest

#define txnmgr_api

#else

#define txnmgr_api __declspec(dllimport)

#endif

#endif

這樣,在測試工程中,txnmgr_api巨集的定義為空,自然被忽略了,而不會影響到產品**。

感覺著這種方法的好處在於只要在一開始做一些小小的修改,便可以一勞永逸的解決訪問所有產品類所有私有成員的問題;由於我們改變的只是成員的訪問級別,對類的行為應該沒有什麼影響。

更新:所以,除非你對以上兩點十分清楚並且可以接受,不然,還是使用官方的friend_test要更好一些。

更新2:

#define private public的乙個致命問題在於如果你使用的那個類是事先編譯好的dll或lib,你改變訪問修飾符使用這個已經被編譯好的類極有可能出現link error --- 因為你壓根用的就是另外乙個類了。現實中,我們或多或少,或直接或間接的會用到其他的庫,所以這麼做是應該被禁止的。 這點其實是萬同學提出來的第二點的擴充套件。

python 類私有成員

在python中定義私有變數只需要在變數名或函式名前加上 兩個下劃線,那麼這個函式或變數就會為私有的了。created on 2012 7 24 author administrator class test def test 1 self print test 1 is ok.def test 2...

Python類的私有成員

usr bin env python coding utf8 python中類的成員函式 成員變數預設都是公開的 public 在python中定義私有成員只需要在變數名或函式名前加上 兩個下劃線 那麼這個函式或變數就變成私有的了。在內部,python使用一種name mangling技術,將 me...

類的繼承私有成員問題

類的繼承過程分為公有繼承,保護繼承和私有繼承,無論哪一種繼承,基類的私有成員在派生類成員中都是不可見的,可是基類的私有成員是否被派生類繼承了呢?通過以下實驗即可知道。如下 include using namespace std class base private virtual void f in...