• <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 肥仔 閱讀(1859) 評論(0)  編輯 收藏 引用 所屬分類: 庫 & 代碼段

            久久久久久久久久久精品尤物| 亚洲AV无码久久| 国产精品日韩深夜福利久久| 国产激情久久久久影院老熟女免费| 超级碰久久免费公开视频| 久久婷婷五月综合成人D啪| 国产精品久久99| 香蕉久久永久视频| 国产午夜久久影院| 狠狠色婷婷久久一区二区| 国产精品久久久久久影院| 一级a性色生活片久久无少妇一级婬片免费放| 国产69精品久久久久APP下载| 国产精品无码久久久久久| 久久只有这里有精品4| 91精品国产91久久| 久久久久亚洲AV片无码下载蜜桃 | 久久这里只有精品首页| 久久久久久亚洲AV无码专区| 色诱久久av| 狠狠久久综合| 久久亚洲国产精品一区二区| 久久久久亚洲AV片无码下载蜜桃| 国产精品免费看久久久香蕉| 久久99精品国产99久久| 精品一二三区久久aaa片| 久久综合九色欧美综合狠狠| 久久亚洲综合色一区二区三区| 色综合久久综合中文综合网| 久久久久99这里有精品10| 久久久久久无码国产精品中文字幕| 久久久久高潮毛片免费全部播放 | 亚洲精品成人久久久| 国产精品狼人久久久久影院| 97精品伊人久久大香线蕉app | 一本久久精品一区二区| 精品久久久久国产免费| 国产福利电影一区二区三区久久老子无码午夜伦不 | 色综合久久最新中文字幕| 色偷偷888欧美精品久久久| 欧美久久精品一级c片片|