簡體   English   中英

Mocking C++ 標准庫

[英]Mocking the C++ Standard Library

我在 C++ 中對 class 進行單元測試,一些公共方法稱為私有方法。 我知道約定是測試公共接口,但類的功能取決於這些私有方法如何依次調用其他類及其方法。 這類似於公共接口,無論私有 function 發生什么情況,它仍然符合 API。

在大多數情況下,我已經能夠模擬私有 function 中調用的類來測試 API,但在少數情況下,我遇到了引用標准庫但沒有設法模擬它的地方。 mocking 標准庫類等有什么技巧嗎? 還是我應該跳過它們?

-- 此外,我無法更改源或使用 mocking 庫。

為此,我建議您使用 Typemock Isolator++ API,它允許在沒有任何重新定義的情況下模擬全局方法。 看,這多么容易:

FAKE_GLOBAL(fopen);
WHEN_CALLED(fopen(0,0)).Return(_anotherFile);

而且您甚至不需要更改源代碼。

如果您嘗試對類的私有方法進行一些白盒測試,也許您的編譯器會讓您繞過訪問控制? GCC 至少允許-fno-access-control ,我在白盒單元測試和數據結構自省方面都非常成功地使用了它,即 hash 在unordered_{set,map}中的沖突。

如果您真的想狡猾,跳過訪問控制還可以讓您直接在其他調用之間使用成員變量。

如果您真的希望模擬標准庫,那么最簡單(可能唯一)的方法是正確檢測您的代碼。 也就是說,您必須使用中間名稱,而不是直接使用標頭和std命名空間。

所以發明一個命名空間,稱之為mstd 在您的模擬模式下,這將是您的模擬命名空間。 在非模擬模式下,這將只是std的別名。

對於 header 文件,您必須避免直接包含標准頭文件,但使用 mocking 層。 因此,您可以包含<mk-map>而不是包含<map> map> 。 這個 header 文件將在標准庫和您的版本之間做出決定。 或許是這樣的:

#ifdef MOCK_MODE
    #include "mock/map.hpp"
#else
    #include <map>
#endif

您可以交替地為您的編譯器提供不同的包含路徑,該路徑位於標准庫之前。 但是,由於無論如何您都必須為命名空間起別名,您仍然必須修改所有代碼——因此包含這些特殊標頭同樣容易。

這是我能看到這個工作的唯一方法。 請注意,使用 LD_PRELOAD 或任何庫技術將不起作用:C++ 標准庫由許多模板類和內聯函數組成。 您需要在編譯時立即替換它們。

真的有必要制作標准庫的模型嗎? 當然,標准庫函數可能存在錯誤,但您的模型可能比實際更可能存在錯誤。

我會說按原樣使用它們。 如果您追蹤到標准庫的測試失敗,那么您就發現了標准庫錯誤。 而且,至少在短期內,您可能必須找到解決此類錯誤的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM