欧美大屁股bbbbxxxx,狼人大香伊蕉国产www亚洲,男ji大巴进入女人的视频小说,男人把ji大巴放进女人免费视频,免费情侣作爱视频

歡迎來到入門教程網(wǎng)!

C語言

當(dāng)前位置:主頁 > 軟件編程 > C語言 >

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

來源:本站原創(chuàng)|時(shí)間:2020-01-10|欄目:C語言|點(diǎn)擊: 次

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

那么什么樣的數(shù)據(jù)庫是好的單元測(cè)試呢,根據(jù)筆者的經(jīng)驗(yàn),以下幾點(diǎn)可能是必須的:

1. 運(yùn)行速度快,對(duì)于一個(gè)有幾百個(gè)單元測(cè)試用例的測(cè)試來說,我期待1-2分鐘內(nèi)可以運(yùn)行完成,應(yīng)為如果我在重構(gòu)代碼,這可以讓我在很快的時(shí)間內(nèi)得到反饋。

2. 不要依賴外部因素,單元測(cè)試只針對(duì)單一函數(shù)功能測(cè)試

3. 一個(gè)用例只測(cè)試一個(gè)函數(shù)

對(duì)于其中的第二點(diǎn),可能是比較麻煩的,因?yàn)椋绻粋€(gè)函數(shù)是類型的成員函數(shù),那么很可能會(huì)依賴很多內(nèi)部的成員變量,這種情況就是mock出場(chǎng)的時(shí)候了,因?yàn)槭褂胢ock才能讓我們專注于自己函數(shù)一業(yè)務(wù)邏輯的測(cè)試,而將依賴隔離開。筆者使用過很多種語言的mock庫,用的最順手的還是Java的mokito, 當(dāng)然c++ 語言也有很多類似的產(chǎn)品,比如gmock, fake it, 但是其局限性確實(shí)比較多,如果不在代碼開始階段了解,并且做好計(jì)劃,后期想加入單元測(cè)試,并且使用gmock的時(shí)候可能就會(huì)追悔莫及,大動(dòng)干戈,下面我們來分場(chǎng)景分析一下這些局限性。

場(chǎng)景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));
}

結(jié)果1:

結(jié)論一:

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

場(chǎng)景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));
}

結(jié)果2:

結(jié)論二:

將函數(shù)改為虛函數(shù),測(cè)試用例通過

場(chǎng)景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));
}

結(jié)果3:

結(jié)論三:

測(cè)試用例通過,派生類中的同名函數(shù)仍然是虛函數(shù),同樣支持多態(tài),支持gomck

場(chǎng)景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));
}

結(jié)果4:

結(jié)論四:

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

結(jié)論

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

上一篇:C++實(shí)現(xiàn)日期類(Date)

欄    目:C語言

下一篇:C語言實(shí)現(xiàn)快速排序改進(jìn)版

本文標(biāo)題:詳解c++種gmock單元測(cè)試框架

本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/686.html

網(wǎng)頁制作CMS教程網(wǎng)絡(luò)編程軟件編程腳本語言數(shù)據(jù)庫服務(wù)器

如果侵犯了您的權(quán)利,請(qǐng)與我們聯(lián)系,我們將在24小時(shí)內(nèi)進(jìn)行處理、任何非本站因素導(dǎo)致的法律后果,本站均不負(fù)任何責(zé)任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權(quán)所有