• <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可以是全局/靜態函數或函數對象.

            Invoke(object_pointer, &class::method)

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

            InvokeWithoutArgs(f)

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

            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)

            每次發動時執行a1an的所有動作.

            IgnoreResult(a)

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

            WithArg<N>(a)

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

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

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

            WithoutArgs(a)

            無參數執行動作a.

            基數(Cardinalities)

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

            AnyNumber()

            函數可以被調用任意次.

            AtLeast(n)

            預計至少調用n.

            AtMost(n)

            預計至多調用n.

            Between(m, n)

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

            Exactly(n) n

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

            序列(Sequences)

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

            建立序列:

             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的生命周期內的所有預期的調用必須以精確的順序發生. 至于名字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 肥仔 閱讀(1862) 評論(0)  編輯 收藏 引用 所屬分類: 庫 & 代碼段

            久久综合狠狠综合久久激情 | 久久中文字幕人妻熟av女| 国产亚洲色婷婷久久99精品| 麻豆av久久av盛宴av| 亚洲国产成人精品91久久久 | 久久久久久A亚洲欧洲AV冫 | 久久天天躁夜夜躁狠狠| 久久久这里有精品| 亚洲综合熟女久久久30p| 亚洲人成伊人成综合网久久久| 久久久久久久波多野结衣高潮| 久久精品国产亚洲AV香蕉| 无码伊人66久久大杳蕉网站谷歌| 亚洲日本va中文字幕久久| av无码久久久久久不卡网站| 韩国无遮挡三级久久| 精品人妻伦九区久久AAA片69| 久久人人超碰精品CAOPOREN| 超级97碰碰碰碰久久久久最新| 东方aⅴ免费观看久久av| 国产精品毛片久久久久久久| 亚洲国产成人久久精品影视| 久久久WWW成人免费精品| 成人久久免费网站| 久久综合丝袜日本网| 婷婷久久综合| 97精品国产91久久久久久| 久久精品国产一区二区三区不卡| 久久人做人爽一区二区三区| 国产成人久久精品一区二区三区 | 亚洲国产成人乱码精品女人久久久不卡 | 日本久久久久久中文字幕| 热久久国产欧美一区二区精品| 热99RE久久精品这里都是精品免费| 久久久久亚洲Av无码专| 久久996热精品xxxx| 国产成人精品白浆久久69| 色婷婷噜噜久久国产精品12p| 久久99亚洲网美利坚合众国| 一级做a爰片久久毛片人呢| 亚洲精品乱码久久久久久按摩|