• <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

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

            [譯]Google C++ Mocking Framework Cheat Sheet

            Google C++ Mocking Framework Cheat Sheet中文版

             

            ·                     定義一個模擬(Mock)

            ·                                模擬(Mocking)普通類

            ·                                模擬(Mocking)模板類

            ·                                為模擬函數(Mock Functions)指定調用約定

            ·                     在測試中使用模擬

            ·                     設置默認動作(Default Actions)

            ·                     設置預期(Expectations)

            ·                     匹配器(Matchers)

            ·                                通配符

            ·                                一般比較

            ·                                浮點數匹配器

            ·                                字符串匹配器

            ·                                容器匹配器

            ·                                成員匹配器

            ·                                匹配函數或函數對象的返回值

            ·                                指針匹配器

            ·                                使用函數或函數對象作為匹配器

            ·                                多參數匹配器

            ·                                復合匹配器

            ·                                轉換匹配器

            ·                                匹配器作為謂詞(Predicates)

            ·                                匹配器作為測試斷言

            ·                     動作(Actions)

            ·                                返回一個值

            ·                                副作用(Side Effects)

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

            ·                                默認動作(Default Action)

            ·                                復合動作(Composite Actions)

            ·                     基數(Cardinalities)

            ·                     序列(Sequences)

            ·                     驗證并重置Mock

             

            定義一個模擬(Mock)

            模擬(Mocking)普通類

            假設有

             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)來忽略所有不關心的調用,或者是一個"精確"的模擬對象讓這些調用置為失敗:

            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));
            };

            為模擬函數(Mock Functions)指定調用約定

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

            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.                可選的,設置模擬對象的默認動作.

            4.                在模擬對象上設置你的預期(它們怎樣被調用,應該怎樣回應?).

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

            6.                當模擬對象析構后,Google Mock 自動驗證它是否達到所有預期.

             

            這里是一個例子:

            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.                 // ... 其它默認動作 ...

            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

            設置默認動作

            對于返回void, bool, 數值, 或指針的函數, Google Mock 都有一個內置默認動作.

            要自定義返回類型為T的函數的默認動作:

            1.                using testing::DefaultValue;

            2.                 

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

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

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

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

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

            設置預期(Expectations)

            EXPECT_CALL()在模擬方法(mock method)上設置預期(它們怎樣被調用?應該怎樣回應?):

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

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

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

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

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

            沒用EXPECT_CALL()的方法可以自由地調用任意次, 并以默認動作應對每次調用.

            匹配器(matcher)

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

            通配符

            _

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

            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.當模擬函數被重載時你可能需要用它來代替Eq(value).

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

            浮點數匹配器

            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所使用的一樣). 它們基于預期的絕對值自動選擇一個合理的誤差范圍. DoubleEq()FloatEq()符合IEEE標準, 該標準要求比較兩個NaN是否相等時返回false. NanSensitive* 版本則視兩個NaN為相等, 這是用戶通常所希望的.

            字符串匹配器

            argument可以是C風格字符串或C++string對象:

            ContainsRegex(string)

            argument 匹配給定的正則表達式.

            EndsWith(suffix)

            argument 含有后綴suffix.

            HasSubstr(string)

            argument 含有子串string.

            MatchesRegex(string)

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

            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-風格容器支持==, 所以你可以使用Eq(expected_container)或簡單地expected_container來精確匹配容器. 如果你想直接寫元素或更靈活地匹配, 可以使用:

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

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

            ElementsAreArray(array) ElementsAreArray(array, count)

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

            成員匹配器

            Field(&class::field, m)

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

            Property(&class::property, m)

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

            匹配函數或函數對象的返回值

            ResultOf(f, m)

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

            指針匹配器

            Pointee(m)

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

            使用函數或函數對象作為匹配器

            Truly(predicate)

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

            多參數匹配器

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

            Eq()

            arg1 == arg2

            Ge()

            arg1 >= arg2

            Gt()

            arg1 > arg2

            Le()

            arg1 <= arg2

            Lt()

            arg1 < arg2

            Ne()

            arg1 != arg2

            復合匹配器

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

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

            argument 匹配所有的匹配器m1mn.

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

            argument 至少匹配m1mn中的一個.

            Not(m)

            argument 不與匹配器m匹配.

            轉換匹配器

            MatcherCast<T>(m)

            轉換匹配器mMatcher<T>類型.

            匹配器作為謂詞 (Predicates)

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

            匹配器作為測試斷言

            ASSERT_THAT(expression, m)

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

            EXPECT_THAT(expression, m)

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

            動作(Actions)

            動作 (Actions)指定了一個模擬函數被調用時應該做什么.

            返回一個值

            Return()

            從一個void的模擬函數中返回

            Return(value)

            返回value.

            ReturnNull()

            返回NULL指針.

            ReturnRef(variable)

            返回variable的引用.

            副作用(Side Effects)

            Assign(&variable, value)

            variable 賦值value.

            SetArgumentPointee<N>(value)

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

            SetArrayArgument<N>(first, last)

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

            SetErrnoAndReturn(error, value)

            設置errnoerror,并且返回value.

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

            Invoke(f)

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

            Invoke(object_pointer, &class::method)

            使用模擬函數的參數調用object_pointer對象的mothod方法.

            InvokeWithoutArgs(f)

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

            InvokeWithoutArgs(object_pointer, &class::method)

            無參數調用object_pointer對象的mothod方法.

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

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

            這里調用函數的返回值將作為動作的返回值.

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

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

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

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

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

            默認動作(Default Actions)

            DoDefault()

            使用默認動作(ON_CALL()指定或內置).

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

            復合動作(Composite Actions)

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

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

            IgnoreResult(a)

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

            WithArg<N>(a)

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

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

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

            WithoutArgs(a)

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

            基數(Cardinalities)

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

            AnyNumber()

            函數可以被調用任意次.

            AtLeast(n)

            預計至少調用n.

            AtMost(n)

            預計至多調用n.

            Between(m, n)

            預計調用次數在mn(包括n)之間.

            Exactly(n) n

            預計精確調用n. 特別是, n0,函數應該永遠不被調用.

            序列(Sequences)

            序列 (Sequences) 指定預期的順序. 在同一序列里的所有預期調用必須按它們指定的順序發(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()之前被調用; 之后兩個則可以任意順序.)

            方便地在一個序列中放入多個預期:

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

            (dummy的生命周期內的所有預期的調用必須以精確的順序發(fā)生. 至于名字dummy與此無關.)

            驗證并重置 Mock

            當模板對象析構時Google Mock將驗證其上的所有預期, 或者你也可以提前做這些事:

            1.                using testing::Mock;

            2.                ...

            3.                // mock_obj進行驗證并移除所有預期;

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

            5.                Mock::VerifyAndClearExpectations(&mock_obj);

            6.                ...

            7.                // mock_obj進行驗證并移除所有預期;

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

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

            10.            Mock::VerifyAndClear(&mock_obj);

             

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

            91精品免费久久久久久久久| 久久精品免费大片国产大片| 一级做a爰片久久毛片16| 无码任你躁久久久久久| 7777久久亚洲中文字幕| 国内精品久久久久久久coent | 久久久久亚洲av成人无码电影| 一本色道久久88精品综合 | 久久国产色AV免费看| 久久久久久国产精品免费免费| 精品永久久福利一区二区| 久久久久亚洲av综合波多野结衣| 2020最新久久久视精品爱 | 久久精品国产99久久无毒不卡 | 奇米综合四色77777久久| 热综合一本伊人久久精品| 久久er国产精品免费观看2| 久久久久久久久久久精品尤物| 久久99精品国产麻豆蜜芽| 久久国产精品-国产精品| 久久精品欧美日韩精品| 无码人妻久久一区二区三区 | 久久国产免费直播| 久久中文字幕一区二区| 狠狠色丁香久久综合五月| 久久精品国产亚洲av麻豆色欲| 久久久午夜精品福利内容| 亚洲国产综合久久天堂| 青青热久久国产久精品 | 国产一区二区精品久久岳| 久久99中文字幕久久| 青青草国产精品久久久久| 久久天堂电影网| 四虎国产精品免费久久5151| 久久成人影院精品777| 青青热久久综合网伊人| 情人伊人久久综合亚洲| 国产精品永久久久久久久久久| 国内精品免费久久影院| 久久91这里精品国产2020| 四虎久久影院|