亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

詳解c++種gmock單元測試框架

2020-05-23 13:26:29
字體:
來源:轉載
供稿:網友

隨著微服務和CI的流行,在目前的軟件工程領域中單元測試可以說是必不可少的一個環節,在TDD中,單元測試更是被提高到了一個新的高度。但是很多公司由于很多不同的原因,沒有能持續維護,或者干脆就從來沒有寫過單元測試,確實,單元測試在初期和代碼維護期會需要花一些投入,但是,如果一個項目是需要長期維護和更新的,那么單元測試的作用,相對于投入來說就根本不算什么。見過很多人寫的單元測試,雖然也可以運行,也有覆蓋率,但是稍微分析一下就會看出來,那根本就不是單元測試,而已經是集成測試,比如有人竟然要在單元測試中訪問網絡,寫文件,甚至讀寫數據庫。。

那么什么樣的數據庫是好的單元測試呢,根據筆者的經驗,以下幾點可能是必須的:

1. 運行速度快,對于一個有幾百個單元測試用例的測試來說,我期待1-2分鐘內可以運行完成,應為如果我在重構代碼,這可以讓我在很快的時間內得到反饋。

2. 不要依賴外部因素,單元測試只針對單一函數功能測試

3. 一個用例只測試一個函數

對于其中的第二點,可能是比較麻煩的,因為,如果一個函數是類型的成員函數,那么很可能會依賴很多內部的成員變量,這種情況就是mock出場的時候了,因為使用mock才能讓我們專注于自己函數一業務邏輯的測試,而將依賴隔離開。筆者使用過很多種語言的mock庫,用的最順手的還是Java的mokito, 當然c++ 語言也有很多類似的產品,比如gmock, fake it, 但是其局限性確實比較多,如果不在代碼開始階段了解,并且做好計劃,后期想加入單元測試,并且使用gmock的時候可能就會追悔莫及,大動干戈,下面我們來分場景分析一下這些局限性。

場景1:

class TurtleReal {public: void PenUp() { } void PenDown()  { }};class MockTurtleReal : public TurtleReal {public: MOCK_METHOD0(PenUp, void()); MOCK_METHOD0(PenDown, void());};class PainterdReal{ TurtleReal* turtle;public: PainterdReal(TurtleReal* turtle)  : turtle(turtle) {} bool DrawCircle(int, int, int) {  turtle->PenDown();  return true; }};TEST(PainterTest, ChildRealCanDrawSomething) { MockTurtleReal turtle; EXPECT_CALL(turtle, PenDown())  .Times(AtLeast(1)); PainterdReal painter(&turtle); EXPECT_TRUE(painter.DrawCircle(0, 0, 10));}

結果1:

c++,gmock,單元測試框架

結論一:

為什么用例會失敗呢,gmock 依賴C++多態機制進行工作,只有虛函數才能被mock, 非虛函數不能被mock, 這一點告訴我們,如果想要在代碼中使用gmock類的設計中,最好采用接口隔離,對于c++來說也就是采用純虛類型,因為c++本身沒有接口類型。

場景2:

class Turtle {public: virtual ~Turtle() {} virtual void PenUp() = 0; virtual void PenDown() = 0;};class MockTurtle : public Turtle {public: MOCK_METHOD0(PenUp, void()); MOCK_METHOD0(PenDown, void());};class Painter{ Turtle* turtle;public: Painter(Turtle* turtle)  : turtle(turtle) {} bool DrawCircle(int, int, int) {  turtle->PenDown();  return true; }};TEST(PainterTest, CanDrawSomething) { MockTurtle turtle; EXPECT_CALL(turtle, PenDown())  .Times(AtLeast(1)); Painter painter(&turtle); EXPECT_TRUE(painter.DrawCircle(0, 0, 10));}

結果2:

c++,gmock,單元測試框架

結論二:

將函數改為虛函數,測試用例通過

場景3:

class TurtleChild: Turtle {public: void PenUp() {  int a = 0; }; void PenDown() {  int b = 0; };};class MockTurtleChild : public TurtleChild {public: MOCK_METHOD0(PenUp, void()); MOCK_METHOD0(PenDown, void());};class PainterChildRef{ TurtleChild turtle;public: PainterChildRef(TurtleChild& turtle)  : turtle(turtle) {} bool DrawCircle(int, int, int) {  turtle.PenDown();  return true; }};TEST(PainterTest, ChildCanDrawSomething) { MockTurtleChild turtle; EXPECT_CALL(turtle, PenDown())  .Times(AtLeast(1)); PainterChild painter(&turtle); EXPECT_TRUE(painter.DrawCircle(0, 0, 10));}

結果3:

c++,gmock,單元測試框架

結論三:

測試用例通過,派生類中的同名函數仍然是虛函數,同樣支持多態,支持gomck

場景4:

class Turtle {public: virtual ~Turtle() {} virtual void PenUp() = 0; virtual void PenDown() = 0;};class TurtleChild: Turtle {public: void PenUp() {  int a = 0; }; void PenDown() {  int b = 0; };}; class MockTurtleChild : public TurtleChild { public: MOCK_METHOD0(PenUp, void()); MOCK_METHOD0(PenDown, void());};class PainterChildRef{ TurtleChild turtle;public: PainterChildRef(TurtleChild& turtle)  : turtle(turtle) {} bool DrawCircle(int, int, int) {  turtle.PenDown();  return true; }};TEST(PainterTest, ChildRefCanDrawSomething) { MockTurtleChild turtle; EXPECT_CALL(turtle, PenDown())  .Times(AtLeast(1)); PainterChildRef painter(turtle); EXPECT_TRUE(painter.DrawCircle(0, 0, 10));}

結果4:

c++,gmock,單元測試框架

結論四:

測試用例失敗,以引用類型傳入的成員變量本身不具備多態特性,因此gmock不支持

結論

本文通過四個場景,層層遞進,深入的剖析了gmock的使用,希望大家在寫代碼之前早做打算,避免大動干戈,返工重來。但是從另一個方面來說,接口隔離, p-impl 慣用法等技術,應該是一個c++老鳥的必備法寶,可見好多東西都是有其道理的,前期不了解,后期只能花更多的精力取彌補,要么推翻重構,要么直接放棄,無知者無畏,no zuo, no die..


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产91在线视频| 成人欧美在线视频| 色在人av网站天堂精品| 亚洲女成人图区| 美女性感视频久久久| 91免费视频国产| 欧美精品免费播放| 欧美超级乱淫片喷水| 日韩中文字幕久久| 亚洲伦理中文字幕| 久久久久久成人精品| 亚洲成人网在线观看| 欧美激情区在线播放| 精品magnet| 欧美性猛交xxxx乱大交3| 精品国产91久久久久久| 国产精品吊钟奶在线| www.欧美免费| 97超级碰碰人国产在线观看| 亚洲免费小视频| 欧美在线视频免费| 日本人成精品视频在线| 国产一区二区三区在线播放免费观看| 国产精自产拍久久久久久蜜| 国产一区二区激情| 欧美一级黄色网| 国产精品99免视看9| 亚洲欧洲国产伦综合| 欧美日本国产在线| 国产亚洲精品高潮| 国产精品一区二区在线| 国产精品网址在线| 伊人一区二区三区久久精品| 久久国产精品首页| 91亚洲国产成人久久精品网站| 欧美综合一区第一页| 91在线观看免费高清| 国产精品久久久久久亚洲调教| 91av在线看| 欧美在线视频在线播放完整版免费观看| 欧洲成人午夜免费大片| 91国内精品久久| 国产欧美在线播放| 欧美激情女人20p| 久久久伊人欧美| 亚洲国产日韩一区| 亚洲91精品在线| 亚洲欧美一区二区三区情侣bbw| 日韩欧亚中文在线| 日本一区二区在线播放| 久久久久久美女| 久久视频在线直播| 亚洲自拍在线观看| 国产精品视频午夜| 国产中文字幕日韩| 欧美亚洲日本网站| 亚洲精品成人久久电影| 亚洲va欧美va国产综合剧情| 成人网在线免费观看| 欧美片一区二区三区| 2019中文字幕在线免费观看| 国产视频久久久| 久久久999精品免费| 亚洲国产精品va在看黑人| 亚洲人精选亚洲人成在线| 欧美电影免费观看高清完整| 91国产精品视频在线| 亚洲第一二三四五区| 国产一区二区三区高清在线观看| 亚洲精品国偷自产在线99热| 九九热视频这里只有精品| 在线观看中文字幕亚洲| 欧美国产精品人人做人人爱| 亚洲a成v人在线观看| 国产日韩欧美在线| 久热精品在线视频| 97国产一区二区精品久久呦| 日韩欧美亚洲一二三区| 国产99久久精品一区二区 夜夜躁日日躁| 亚洲欧美国产精品va在线观看| 福利二区91精品bt7086| 国产成人精彩在线视频九色| xxxxx成人.com| 不卡在线观看电视剧完整版| 国产精品美女免费看| 久久手机免费视频| 性亚洲最疯狂xxxx高清| 久久久视频在线| 日本一欧美一欧美一亚洲视频| 亚洲精品一区av在线播放| 国产精品日韩在线一区| 久久精品99无色码中文字幕| 亚洲在线免费观看| 国产精品网站大全| 欧美精品生活片| 一本一本久久a久久精品综合小说| 成人午夜黄色影院| 国产成人精品在线| 在线播放日韩av| 日韩美女视频在线观看| 久久国产加勒比精品无码| 欧美在线一区二区三区四| 欧美又大粗又爽又黄大片视频| 欧美又大又硬又粗bbbbb| 国产不卡视频在线| 国产精品久久久久一区二区| 这里只有精品丝袜| 中文字幕亚洲一区二区三区五十路| 亚洲第一网站男人都懂| 国产97色在线| 亚洲午夜久久久影院| 久久精品国产亚洲7777| 欧美日韩在线视频首页| 日本精品久久中文字幕佐佐木| 97久久久免费福利网址| 精品国产乱码久久久久酒店| 亚洲精品不卡在线| 欧美日韩中文在线| 精品久久久久久久久久久久| 亚洲成人黄色网址| 国产免费一区二区三区在线能观看| 亚洲综合精品一区二区| 亚洲国产精品成人精品| 这里只有精品久久| 亚洲成人精品久久| 亚洲第一福利网站| 久久九九热免费视频| 一区二区三区四区在线观看视频| 国产脚交av在线一区二区| 亚洲精品一区中文字幕乱码| 国产精品444| 亚洲xxxx视频| 亚洲视频视频在线| 欧美精品久久久久久久久| 91免费观看网站| 欧美午夜精品久久久久久久| 国产精品啪视频| 国产精品偷伦免费视频观看的| 欧美性高跟鞋xxxxhd| 国产精品美女在线观看| 色视频www在线播放国产成人| 久久色免费在线视频| 97精品久久久中文字幕免费| 久久av在线看| 亚洲在线免费观看| 亚洲跨种族黑人xxx| 日本在线精品视频| 国产精品第二页| 免费av一区二区| 亚洲欧洲日产国产网站| 亚洲国产另类 国产精品国产免费| 亚洲欧美国内爽妇网| 成人激情电影一区二区| 国产精品99久久久久久www| 亚洲韩国欧洲国产日产av| 久久九九国产精品怡红院| 国产69精品99久久久久久宅男| 精品一区精品二区| 欧美激情网友自拍| 国产精品国产亚洲伊人久久| 国产精品无码专区在线观看| 亚洲色图50p| 91高清视频免费观看| 国产精品揄拍一区二区|