• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            [譯]Google C++ Mocking Framework Cheat Sheet

            Google C++ Mocking Framework Cheat Sheet中文版

             

            ·                     定義一個模擬(Mock)

            ·                                模擬(Mocking)普通類

            ·                                模擬(Mocking)模板類

            ·                                為模擬函數(shù)(Mock Functions)指定調(diào)用約定

            ·                     在測試中使用模擬

            ·                     設(shè)置默認(rèn)動作(Default Actions)

            ·                     設(shè)置預(yù)期(Expectations)

            ·                     匹配器(Matchers)

            ·                                通配符

            ·                                一般比較

            ·                                浮點數(shù)匹配器

            ·                                字符串匹配器

            ·                                容器匹配器

            ·                                成員匹配器

            ·                                匹配函數(shù)或函數(shù)對象的返回值

            ·                                指針匹配器

            ·                                使用函數(shù)或函數(shù)對象作為匹配器

            ·                                多參數(shù)匹配器

            ·                                復(fù)合匹配器

            ·                                轉(zhuǎn)換匹配器

            ·                                匹配器作為謂詞(Predicates)

            ·                                匹配器作為測試斷言

            ·                     動作(Actions)

            ·                                返回一個值

            ·                                副作用(Side Effects)

            ·                                使用函數(shù)或函數(shù)對象作為動作(Action)

            ·                                默認(rèn)動作(Default Action)

            ·                                復(fù)合動作(Composite Actions)

            ·                     基數(shù)(Cardinalities)

            ·                     序列(Sequences)

            ·                     驗證并重置Mock

             

            定義一個模擬(Mock)

            模擬(Mocking)普通類

            假設(shè)有

             class Foo {
             ...
             virtual ~Foo();
             virtual int GetSize() const = 0;
             virtual string Describe(const char* name) = 0;
             virtual string Describe(int type) = 0;
             virtual bool Process(Bar elem, int count) = 0;
            };

            (注意 ~Foo() 必須virtual) 我們可以如下定義它的模擬類

             #include <gmock/gmock.h>
             
            class MockFoo : public Foo {
             MOCK_CONST_METHOD0(GetSize, int());
             MOCK_METHOD1(Describe, string(const char* name));
             MOCK_METHOD1(Describe, string(int type));
             MOCK_METHOD2(Process, bool(Bar elem, int count));
            };

            如下,建立一個"合適"的模擬對象 (mock object)來忽略所有不關(guān)心的調(diào)用,或者是一個"精確"的模擬對象讓這些調(diào)用置為失敗:

            NiceMock<MockFoo> nice_foo; // The type is a subclass of MockFoo.
            StrictMock<MockFoo> strict_foo; // The type is a subclass of MockFoo.

            模擬(Mocking)模板類

            要模擬

             template <typename Elem>
            class StackInterface {
             ...
             virtual ~StackInterface();
             virtual int GetSize() const = 0;
             virtual void Push(const Elem& x) = 0;
            };

            (注意 ~StackInterface() 必須 virtual ) 只要追加_T MOCK_* 宏即可:

             template <typename Elem>
            class MockStack : public StackInterface<Elem> {
             ...
             MOCK_CONST_METHOD0_T(GetSize, int());
             MOCK_METHOD1_T(Push, void(const Elem& x));
            };

            為模擬函數(shù)(Mock Functions)指定調(diào)用約定

            如果你模擬的函數(shù)不是使用默認(rèn)的調(diào)用約定,你可以追加 _WITH_CALLTYPE 到前兩段講到的所有宏里,并把調(diào)用約定作為宏的第一個參數(shù),例如,

            MOCK_METHOD_1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int n));
             MOCK_CONST_METHOD2_WITH_CALLTYPE(
                  STDMETHODCALLTYPE, Bar, int(double x, double y));

            這里的 STDMETHODCALLTYPE Windows中的頭文件 <objbase.h> 定義的.

            在測試中使用模擬(Mocking)

            典型的流程是:

            1.                引入你要用到的 Google Mock 名稱. 除宏或其它特別提到的之外所有 Google Mock 名稱都位于testing 名空間之下.

            2.                建立模擬對象(mock objects).

            3.                可選的,設(shè)置模擬對象的默認(rèn)動作.

            4.                在模擬對象上設(shè)置你的預(yù)期(它們怎樣被調(diào)用,應(yīng)該怎樣回應(yīng)?).

            5.                調(diào)用使用模擬對象的代碼,如有必要,使用Google Test斷言檢查返回值.

            6.                當(dāng)模擬對象析構(gòu)后,Google Mock 自動驗證它是否達(dá)到所有預(yù)期.

             

            這里是一個例子:

            1.                using testing::Return; // #1

            2.                 

            3.                TEST(BarTest, DoesThis) {

            4.                MockFoo foo; // #2

            5.                 

            6.                ON_CALL(foo, GetSize()) // #3

            7.                .WillByDefault(Return(1));

            8.                 // ... 其它默認(rèn)動作 ...

            9.                 

            10.            EXPECT_CALL(foo, Describe(5)) // #4

            11.            .Times(3)

            12.            .WillRepeatedly(Return("Category 5"));

            13.             // ... other expectations ...

            14.             

            15.            EXPECT_EQ("good", MyProductionFunction(&foo)); // #5

            16.            } // #6

            設(shè)置默認(rèn)動作

            對于返回void, bool, 數(shù)值, 或指針的函數(shù), Google Mock 都有一個內(nèi)置默認(rèn)動作.

            要自定義返回類型為T的函數(shù)的默認(rèn)動作:

            1.                using testing::DefaultValue;

            2.                 

            3.                DefaultValue<T>::Set(value); // 設(shè)置默認(rèn)的返回值

            4.                // ... use the mocks ...

            5.                DefaultValue<T>::Clear(); // 重置默認(rèn)值

            要自定義特定方法的默認(rèn)動作,使用ON_CALL():

            ON_CALL(mock_object, method(matchers))
             .WithArguments(multi_argument_matcher) ?
             .WillByDefault(action);

            設(shè)置預(yù)期(Expectations)

            EXPECT_CALL()在模擬方法(mock method)上設(shè)置預(yù)期(它們怎樣被調(diào)用?應(yīng)該怎樣回應(yīng)?):

            EXPECT_CALL(mock_object, method(matchers))
             .WithArguments(multi_argument_matcher) ?
             .Times(cardinality) ?
             .InSequence(sequences) *
             .WillOnce(action) *
             .WillRepeatedly(action) ?
             .RetiresOnSaturation(); ?

            如果沒有Times(), 那么cardinality就依據(jù)其它參數(shù)做出假定:

            ·                     Times(1) 既沒有WillOnce()也沒有WillRepeatedly();

            ·                     Times(n) nWillOnce()但沒有WillRepeatedly(), 這里的n >= 1;

            ·                     Times(AtLeast(n)) nWillOnce()并且有一個WillRepeatedly(), 這里的n >= 0.

            沒用EXPECT_CALL()的方法可以自由地調(diào)用任意次, 并以默認(rèn)動作應(yīng)對每次調(diào)用.

            匹配器(matcher)

            匹配器 (matcher)匹配單個參數(shù)(指函數(shù)參數(shù)). 內(nèi)置的匹配器分成幾種類型(下面的argument指函數(shù)參數(shù)):

            通配符

            _

            argument& nbsp;可以是適當(dāng)類型的任意值

            A<type>() An<type>()

            argument& nbsp;可以是type類型的任意值

            一般比較

            Eq(value) value

            argument == value

            Ge(value)

            argument >= value

            Gt(value)

            argument > value

            Le(value)

            argument <= value

            Lt(value)

            argument < value

            Ne(value)

            argument != value

            NULL

            argument NULL.

            NotNull()

            argument 是一個非null指針.

            Ref(variable)

            argument 是一個variable的引用.

            TypedEq<type>(value)

            argument type類型并且等于value.當(dāng)模擬函數(shù)被重載時你可能需要用它來代替Eq(value).

            除了Ref(), 這些匹配器在測試用例中使用一份value的拷貝來修改或析構(gòu). 如果編譯器提示value沒有public的拷貝構(gòu)造, 可以嘗試使用ByRef()包裝, 比如. Eq(ByRef(non_copyable_value)). 如果你這樣做的話, 請確保調(diào)用之后non_copyable_value沒有被修改.

            浮點數(shù)匹配器

            DoubleEq(a_double)

            argument 是一個double,近似等于a_double, 兩個NaN是不相等的.

            FloatEq(a_float)

            argument 是一個float,近似等于a_float, 兩個NaN是不相等的.

            NanSensitiveDoubleEq(a_double)

            argument 是一個double,近似等于a_double, 兩個NaN是相等的.

            NanSensitiveFloatEq(a_float)

            argument 是一個float,近似等于a_float, 兩個NaN是相等的.

            這些匹配器使用基于ULP的比較 (Google Test所使用的一樣). 它們基于預(yù)期的絕對值自動選擇一個合理的誤差范圍. DoubleEq()FloatEq()符合IEEE標(biāo)準(zhǔn), 該標(biāo)準(zhǔn)要求比較兩個NaN是否相等時返回false. NanSensitive* 版本則視兩個NaN為相等, 這是用戶通常所希望的.

            字符串匹配器

            argument可以是C風(fēng)格字符串或C++string對象:

            ContainsRegex(string)

            argument 匹配給定的正則表達(dá)式.

            EndsWith(suffix)

            argument 含有后綴suffix.

            HasSubstr(string)

            argument 含有子串string.

            MatchesRegex(string)

            argument 從第一個字符到最后一個字符都完全匹配給定的正則表達(dá)式.

            StartsWith(prefix)

            argument 含有前綴prefix.

            StrCaseEq(string)

            argument string相等, 忽略大小寫.

            StrCaseNe(string)

            argument string不等, 忽略大小寫.

            StrEq(string)

            argument string相等.

            StrNe(string)

            argument string不等.

            StrCaseEq(), StrCaseNe(), StrEq(), StrNe() 也能工作于寬字符字符串.

            容器匹配器

            很多STL-風(fēng)格容器支持==, 所以你可以使用Eq(expected_container)或簡單地expected_container來精確匹配容器. 如果你想直接寫元素或更靈活地匹配, 可以使用:

            ElementsAre(e0, e1, ..., en)

            argument n + 1個元素, i個元素匹配ei, 它們可以是一個值或是一個匹配器. 允許010個參數(shù).

            ElementsAreArray(array) ElementsAreArray(array, count)

            ElementsAre()相同, 除了預(yù)期值/匹配器來源于一個C風(fēng)格數(shù)組.

            成員匹配器

            Field(&class::field, m)

            argument.field (argument->field, 當(dāng)argument是一個指針時)與匹配器m匹配, 這里的argument是一個class類的實例.

            Property(&class::property, m)

            argument.property() (argument->property(), 當(dāng)argument是一個指針時)與匹配器m匹配, 這里的argument是一個class類的實例.

            匹配函數(shù)或函數(shù)對象的返回值

            ResultOf(f, m)

            f(argument) 與匹配器m匹配, 這里的f是一個函數(shù)或函數(shù)對象.

            指針匹配器

            Pointee(m)

            argument (不論是智能指針還是原始指針) 指向的值與匹配器m匹配.

            使用函數(shù)或函數(shù)對象作為匹配器

            Truly(predicate)

            predicate(argument) 返回值為true, 這里的predicate是一個函數(shù)或函數(shù)對象.

            多參數(shù)匹配器

            這些匹配器為元組類型(tuple types). 它們可以用在.WithArguments()里匹配兩個參數(shù)的函數(shù):

            Eq()

            arg1 == arg2

            Ge()

            arg1 >= arg2

            Gt()

            arg1 > arg2

            Le()

            arg1 <= arg2

            Lt()

            arg1 < arg2

            Ne()

            arg1 != arg2

            復(fù)合匹配器

            你可以把一個或多個匹配器合成一個匹配器:

            AllOf(m1, m2, ..., mn)

            argument 匹配所有的匹配器m1mn.

            AnyOf(m1, m2, ..., mn)

            argument 至少匹配m1mn中的一個.

            Not(m)

            argument 不與匹配器m匹配.

            轉(zhuǎn)換匹配器

            MatcherCast<T>(m)

            轉(zhuǎn)換匹配器mMatcher<T>類型.

            匹配器作為謂詞 (Predicates)

            通過Matches(m),Google Mock 能讓你轉(zhuǎn)換一個匹配器m到一個無參數(shù)謂詞(就象STL算法使用的一樣).

            匹配器作為測試斷言

            ASSERT_THAT(expression, m)

            如果expression的值和匹配器m不匹配,就產(chǎn)生一個致命失敗.

            EXPECT_THAT(expression, m)

            如果expression的值和匹配器m不匹配,就產(chǎn)生一個非致命失敗.

            動作(Actions)

            動作 (Actions)指定了一個模擬函數(shù)被調(diào)用時應(yīng)該做什么.

            返回一個值

            Return()

            從一個void的模擬函數(shù)中返回

            Return(value)

            返回value.

            ReturnNull()

            返回NULL指針.

            ReturnRef(variable)

            返回variable的引用.

            副作用(Side Effects)

            Assign(&variable, value)

            variable 賦值value.

            SetArgumentPointee<N>(value)

            給第N(0-based)個參數(shù)指向的變量賦值value.

            SetArrayArgument<N>(first, last)

            拷貝源范圍[first, last)里的元素到第N(0- based)個參數(shù)指向的數(shù)組, 它可以是一個指針或一個迭代器. 這個動作不會改變源范圍元素的所有權(quán).

            SetErrnoAndReturn(error, value)

            設(shè)置errnoerror,并且返回value.

            使用函數(shù)或函數(shù)對象作為動作(Actions)

            Invoke(f)

            使用模擬函數(shù)的參數(shù)調(diào)用f, 這里的f可以是全局/靜態(tài)函數(shù)或函數(shù)對象.

            Invoke(object_pointer, &class::method)

            使用模擬函數(shù)的參數(shù)調(diào)用object_pointer對象的mothod方法.

            InvokeWithoutArgs(f)

            無參數(shù)調(diào)用f, 這里的f可以是全局/靜態(tài)函數(shù)或函數(shù)對象.

            InvokeWithoutArgs(object_pointer, &class::method)

            無參數(shù)調(diào)用object_pointer對象的mothod方法.

            InvokeArgument<N>(arg1, arg2, ..., argk)

            調(diào)用模擬函數(shù)的第N(0-based)參數(shù), 這個參數(shù)必須是一個函數(shù)或函數(shù)對象, 傳入這里的k個參數(shù).

            這里調(diào)用函數(shù)的返回值將作為動作的返回值.

            當(dāng)定義一個函數(shù)或函數(shù)對象用于Invoke*(), 你可以使用Unused來聲明一些不用的參數(shù):

            double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); }
             ...
             EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance));

            InvokeArgument<N>(...), 如果一個參數(shù)需要引用傳遞, 可以使用ByRef()包裝. 例如,

             InvokeArgument<2>(5, string("Hi"), ByRef(foo))

            調(diào)用模擬函數(shù)的第二個參數(shù), 以傳值的方式傳入5string("Hi"), 引用的方式傳入foo.

            默認(rèn)動作(Default Actions)

            DoDefault()

            使用默認(rèn)動作(ON_CALL()指定或內(nèi)置).

            注意: 由于技術(shù)原因, DoDefault()不能用于復(fù)合動作 - 嘗試的結(jié)果是一個運行期錯誤.

            復(fù)合動作(Composite Actions)

            DoAll(a1, a2, ..., an)

            每次發(fā)動時執(zhí)行a1an的所有動作.

            IgnoreResult(a)

            執(zhí)行動作a并忽略它的返回值. a不能返回void.

            WithArg<N>(a)

            傳入模擬函數(shù)的第N(0-based)參數(shù)作為動作a的參數(shù)并執(zhí)行之.

            WithArgs<N1, N2, ..., Nk>(a)

            傳入選中的模擬函數(shù)的多個第N(0-based)參數(shù)作為動作a的參數(shù)并執(zhí)行之.

            WithoutArgs(a)

            無參數(shù)執(zhí)行動作a.

            基數(shù)(Cardinalities)

            基數(shù)用于Times()中來指定模擬函數(shù)將被調(diào)用多少次:

            AnyNumber()

            函數(shù)可以被調(diào)用任意次.

            AtLeast(n)

            預(yù)計至少調(diào)用n.

            AtMost(n)

            預(yù)計至多調(diào)用n.

            Between(m, n)

            預(yù)計調(diào)用次數(shù)在mn(包括n)之間.

            Exactly(n) n

            預(yù)計精確調(diào)用n. 特別是, 當(dāng)n0,函數(shù)應(yīng)該永遠(yuǎn)不被調(diào)用.

            序列(Sequences)

            序列 (Sequences) 指定預(yù)期的順序. 在同一序列里的所有預(yù)期調(diào)用必須按它們指定的順序發(fā)生; 反之則可以是任意順序.

            建立序列:

             Sequence s1, s2;

            使用序列:

            EXPECT_CALL(foo, Reset())
             .InSequence(s1, s2)
             .WillOnce(Return(true));
            EXPECT_CALL(foo, GetSize())
             .InSequence(s1)
             .WillOnce(Return(1));
            EXPECT_CALL(foo, Describe(A<const char*>()))
             .InSequence(s2)
             .WillOnce(Return("dummy"));

            (Reset()必須在GetSize()Describe()之前被調(diào)用; 之后兩個則可以任意順序.)

            方便地在一個序列中放入多個預(yù)期:

            {
             InSequence dummy;
             
             EXPECT_CALL(...)...;
             EXPECT_CALL(...)...;
             ...
             EXPECT_CALL(...)...;
            }

            (dummy的生命周期內(nèi)的所有預(yù)期的調(diào)用必須以精確的順序發(fā)生. 至于名字dummy與此無關(guān).)

            驗證并重置 Mock

            當(dāng)模板對象析構(gòu)時Google Mock將驗證其上的所有預(yù)期, 或者你也可以提前做這些事:

            1.                using testing::Mock;

            2.                ...

            3.                // mock_obj進(jìn)行驗證并移除所有預(yù)期;

            4.                // 如果成功返回true.

            5.                Mock::VerifyAndClearExpectations(&mock_obj);

            6.                ...

            7.                // mock_obj進(jìn)行驗證并移除所有預(yù)期;

            8.                // 同時也移除ON_CALL()設(shè)置的默認(rèn)動作;

            9.                // 如果成功返回true.

            10.            Mock::VerifyAndClear(&mock_obj);

             

            posted on 2009-05-02 01:52 肥仔 閱讀(1860) 評論(0)  編輯 收藏 引用 所屬分類: 庫 & 代碼段

            亚洲国产欧洲综合997久久| 久久久久18| 中文国产成人精品久久不卡| 久久久精品久久久久久| 国产成人综合久久精品尤物| 97久久国产亚洲精品超碰热| 伊人久久大香线蕉AV色婷婷色| 久久久久九九精品影院| 国产精品热久久毛片| 伊人久久综在合线亚洲2019| 久久er热视频在这里精品| 99久久精品午夜一区二区| 色妞色综合久久夜夜 | 一本大道久久东京热无码AV| 久久久久亚洲AV无码专区网站 | 四虎久久影院| 亚洲伊人久久综合中文成人网| 蜜臀久久99精品久久久久久| 亚洲v国产v天堂a无码久久| 无码任你躁久久久久久老妇| 亚洲伊人久久综合影院| 久久大香萑太香蕉av| 久久人人爽人人爽人人片AV高清 | 日韩AV无码久久一区二区 | 久久中文字幕一区二区| 久久免费视频网站| 93精91精品国产综合久久香蕉| 丁香五月综合久久激情| 日韩十八禁一区二区久久| 日韩精品无码久久一区二区三| 一本色道久久88综合日韩精品 | 久久精品国产欧美日韩| 伊人久久国产免费观看视频| 人妻无码精品久久亚瑟影视| 婷婷综合久久中文字幕蜜桃三电影| 日产精品久久久久久久性色| 国产精品久久毛片完整版| 久久精品国产亚洲一区二区三区| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 久久青草国产手机看片福利盒子| 久久国产成人午夜AV影院|