程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> Google C++單元測試框架GoogleTest---CheatSheet文檔

Google C++單元測試框架GoogleTest---CheatSheet文檔

編輯:關於C++

Google C++單元測試框架GoogleTest---CheatSheet文檔。本站提示廣大學習愛好者:(Google C++單元測試框架GoogleTest---CheatSheet文檔)文章只能為提供參考,不一定能成為您想要的結果。以下是Google C++單元測試框架GoogleTest---CheatSheet文檔正文


CheatSheet文檔中包括了GMock一切常用的東西,看了這個根本上就可以用它了,本文接上篇博文:Google C++單元測試框架GoogleTest---Google Mock簡介--概念及根底語法 ,建議先看上一篇,再看本篇內容。

本文翻譯自:https://github.com/google/googletest/blob/master/googlemock/docs/CheatSheet.md

一、定義一個模仿類

1. 模仿一個正常的類,就是接口類

  給:

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

(note that ~Foo() must be virtual) we can define its mock as,定義模仿類。

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

創立一個“nice”模仿對象疏忽一切無趣的調用,或一個“strict”模仿對象,將它們視為失敗:

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

2. 模仿一個類模板

To mock:

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

(note that ~StackInterface() must be virtual) just append _T to the MOCK_* macros:

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

3. 指定模仿函數的調用商定

假如您的mock函數不運用默許調用商定,您可以經過將_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>定義。

二、在測試中運用模仿器

典型的流程是:

  1. 導入您需求運用的Google Mock稱號。一切Google Mock稱號都位於測試命名空間中,除非它們是宏或其他正文。
  2. 創立模仿對象。
  3. (可選)設置模仿對象的默許操作。
  4. 設置你對模仿對象的希冀(他們怎樣叫?他們做什麼?)。
  5. 運用模仿對象的練習代碼;如有必要,請運用Google Test斷言反省後果。
  6. 當模仿對象被毀壞時,Google Mock會自動驗證一切對其的希冀能否滿足。

這裡是一個例子:

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

TEST(BarTest, DoesThis) {
  MockFoo foo;                                    // #2

  ON_CALL(foo, GetSize())                         // #3
      .WillByDefault(Return(1));
  // ... other default actions ...

  EXPECT_CALL(foo, Describe(5))                   // #4
      .Times(3)
      .WillRepeatedly(Return("Category 5"));
  // ... other expectations ...

  EXPECT_EQ("good", MyProductionFunction(&foo));  // #5
}                                                 // #6

三、設置默許操作

Google Mock對任何前往void,bool,數值或指針的函數都有一個內置的默許舉措。

要為全局前往類型T的函數自定義默許操作:

using ::testing::DefaultValue;

// Sets the default value to be returned. T must be CopyConstructible.
DefaultValue<T>::Set(value);
// Sets a factory. Will be invoked on demand. T must be MoveConstructible.
//   T MakeT();
DefaultValue<T>::SetFactory(&MakeT);
// ... use the mocks ...
// Resets the default value.
DefaultValue<T>::Clear();

要自定義特定辦法的默許操作,請運用ON_CALL():

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

四、設置希冀

EXPECT_CALL()在模仿辦法上設置希冀(如何調用它?它會做什麼?):

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

假如省略Times(),則基數假定為:

  • Times(1)當沒有WillOnce()和WillRepeatedly();
  • 當有n個WillOnce()但沒有WillRepeatedly()時,Times(n),其中n> = 1; 要麼
  • 當有n個WillOnce()和WillRepeatedly(),其中n> = 0時,Times(AtLeast(n))。

沒有EXPECT_CALL()的辦法可以被恣意調用屢次,並且每次都將采取默許操作。

五、婚配

婚配器婚配單個參數。 您可以在ON_CALL()或EXPECT_CALL()中運用它,或運用它直接驗證值:

EXPECT_THAT(value, matcher)Asserts that value matches matcher. ASSERT_THAT(value, matcher) The same as EXPECT_THAT(value, matcher), except that it generates a fatal failure.

內置的婚配(其中參數是函數參數)分為幾類:

1. 通配符

_argument can be any value of the correct type可以代表恣意類型. A<type>() or An<type>() argument can be any value of type可以是type類型的恣意值.

2. 普通比擬

Eq(value) 或許 value argument == value,method中的形參必需是value Ge(value) argument >= value,method中的形參必需大於等於value Gt(value) argument > value Le(value) argument <= value Lt(value) argument < value Ne(value) argument != value IsNull() method的形參必需是NULL指針 NotNull() argument is a non-null pointer Ref(variable) 形參是variable的援用 TypedEq<type>(value) 形參的類型必需是type類型,而且值必需是value。當模仿函數被重載你能夠需求它而不是Eq(vlaue)

留意** 除了Ref()之外,這些婚配器會創立一個值的正本,以備日後修正或銷毀。 假如編譯器埋怨該值沒有公共正本結構函數,請嘗試將其包裝在ByRef()中,例如。 Eq(ByRef(non_copyable_value))。 假如你這樣做,請確保non_copyable_value之後不改動,否則你的婚配器的含義將被改動。

3. 浮點數的比擬

DoubleEq(a_double) 形參是一個double類型,比方值近似於a_double,兩個NaN是不相等的 FloatEq(a_float) 同上,只不過類型是float NanSensitiveDoubleEq(a_double) 形參是一個double類型,比方值近似於a_double,兩個NaN是相等的,這個是用戶所希望的方式 NanSensitiveFloatEq(a_float) 同上,只不過形參是float

上述婚配器運用基於ULP的比擬(與Google Test中運用的比擬相反)。 它們依據希冀值的相對值自動選擇合理的誤差界線。 DoubleEq()和FloatEq()契合IEEE規范,這需求比擬兩個NaNs的相等性前往false。 NanSensitive *版本將兩個NaNs相等,這通常是用戶想要的。

DoubleNear(a_double, max_abs_error)argument is a double value close to a_double (absolute error <= max_abs_error), treating two NaNs as unequal. FloatNear(a_float, max_abs_error) argument is a float value close to a_float (absolute error <= max_abs_error), treating two NaNs as unequal. NanSensitiveDoubleNear(a_double, max_abs_error) argument is a double value close to a_double (absolute error <= max_abs_error), treating two NaNs as equal. NanSensitiveFloatNear(a_float, max_abs_error) argument is a float value close to a_float (absolute error <= max_abs_error), treating two NaNs as equal.

4. String Matchers

這裡的字符串即可以是C作風的字符串,也可以是C++作風的。

ContainsRegex(string) 形參婚配給定的正則表達式 EndsWith(suffix) 形參以suffix截尾 HasSubstr(string) 形參有string這個子串 MatchesRegex(string) 從第一個字符到最後一個字符都完全婚配給定的正則表達式. StartsWith(prefix) 形參以prefix開端 StrCaseEq(string) 參數等於string,並且疏忽大小寫 StrCaseNe(string) 參數不是string,並且疏忽大小寫 StrEq(string) 參數等於string StrNe(string) 參數不等於string

5. 容器的婚配

很多STL的容器的比擬都支持==這樣的操作,關於這樣的容器可以運用上述的Eq(expected_container)來比擬或許只是expect_container來完全婚配容器。但假如你想寫得更為靈敏,可以運用上面的這些容器婚配辦法:

ContainerEq(container)The same as Eq(container) except that the failure message also includes which elements are in one container but not the other. Contains(e) argument contains an element that matches e, which can be either a value or a matcher. Each(e) argument is a container where every element matches e, which can be either a value or a matcher. ElementsAre(e0, e1, ..., en) argument has n + 1 elements, where the i-th element matches ei, which can be a value or a matcher. 0 to 10 arguments are allowed. ElementsAreArray({ e0, e1, ..., en })ElementsAreArray(array), or ElementsAreArray(array, count) The same as ElementsAre() except that the expected element values/matchers come from an initializer list, STL-style container, or C-style array. IsEmpty() argument is an empty container (container.empty()). Pointwise(m, container) argument contains the same number of elements as in container, and for all i, (the i-th element in argument, the i-th element in container) match m, which is a matcher on 2-tuples. E.g. Pointwise(Le(), upper_bounds) verifies that each element in argument doesn't exceed the corresponding element in upper_bounds. See more detail below. SizeIs(m) argument is a container whose size matches m. E.g. SizeIs(2) or SizeIs(Lt(2)). UnorderedElementsAre(e0, e1, ..., en) argument has n + 1 elements, and under some permutation each element matches an ei (for a different i), which can be a value or a matcher. 0 to 10 arguments are allowed. UnorderedElementsAreArray({ e0, e1, ..., en })UnorderedElementsAreArray(array), or UnorderedElementsAreArray(array, count) The same as UnorderedElementsAre() except that the expected element values/matchers come from an initializer list, STL-style container, or C-style array. WhenSorted(m) When argument is sorted using the < operator, it matches container matcher m. E.g. WhenSorted(UnorderedElementsAre(1, 2, 3)) verifies that argument contains elements 12, and 3, ignoring order. WhenSortedBy(comparator, m) The same as WhenSorted(m), except that the given comparator instead of < is used to sort argument. E.g. WhenSortedBy(std::greater<int>(), ElementsAre(3, 2, 1)).

留意:

  • 這些婚配器也可以婚配:

     i. 經過援用傳遞的本地數組(例如在Foo(const int(&a)[5])中)和

     ii. 作為指針和計數傳遞的數組(例如,在Bar(const T * buffer,int len) - 參見 Multi-argument Matchers)。

  • 婚配的數組可以是多維的(即其元素可以是數組)。

  • 在Pointwise(m,...)中的m應該是:: testing :: tuple <T,U>的婚配器,其中T和U辨別是實踐容器和預期容器的元素類型。 例如,要比擬兩個Foo容器,其中Foo不支持operator ==但是有一個Equals()辦法,可以寫:

using ::testing::get;
MATCHER(FooEq, "") {
  return get<0>(arg).Equals(get<1>(arg));
}
...
EXPECT_THAT(actual_foos, Pointwise(FooEq(), expected_foos));

6. 成員婚配器

Field(&class::field, m)argument.field (or argument->field when argument is a plain pointer) matches matcher m, where argument is an object of type class. Key(e) argument.first matches e, which can be either a value or a matcher. E.g. Contains(Key(Le(5))) can verify that a map contains a key <= 5. Pair(m1, m2) argument is an std::pair whose first field matches m1 and second field matches m2. Property(&class::property, m) argument.property() (or argument->property() when argument is a plain pointer) matches matcher m, where argument is an object of type class.

7. 婚配函數或函數的後果

ResultOf(f, m)f(argument) matches matcher m, where f is a function or functor.

 8. 指針婚配

Pointee(m)

argument (either a smart pointer or a raw pointer) points to a value that matches matcher m.

WhenDynamicCastTo<T>(m)

when argument is passed through dynamic_cast<T>(), it matches matcher m.

 9. 多參數婚配器

從技術上講,完全婚配器婚配單個值。 “多參數”婚配器只是婚配元組的婚配器。 以下婚配器可用於婚配元組(x,y):

Eq()x == y Ge() x >= y Gt() x > y Le() x <= y Lt() x < y Ne() x != y

您可以運用以下選擇器來選擇參數的子集(或對其重新排序)以參與婚配:

AllArgs(m)Equivalent to m. Useful as syntactic sugar in .With(AllArgs(m)). Args<N1, N2, ..., Nk>(m) The tuple of the k selected (using 0-based indices) arguments matches m, e.g. Args<1, 2>(Eq()).

10. 復合婚配

你可以從一個或多個其他婚配器做一個婚配器:

AllOf(m1, m2, ..., mn)argument matches all of the matchers m1 to mn. AnyOf(m1, m2, ..., mn) argument matches at least one of the matchers m1 to mn. Not(m) argument doesn't match matcher m.

11. Adapters for Matchers

MatcherCast<T>(m)casts matcher m to type Matcher<T>. SafeMatcherCast<T>(m) safely casts matcher m to type Matcher<T>. Truly(predicate) predicate(argument) returns something considered by C++ to be true, where predicate is a function or functor.

12 .婚配作為謂詞(Matchers as Predicates)

Matches(m)(value)evaluates to true if value matches m. You can use Matches(m) alone as a unary functor. ExplainMatchResult(m, value, result_listener) evaluates to true if value matches m, explaining the result to result_listener. Value(value, m) evaluates to true if value matches m.

13. 定義婚配

MATCHER(IsEven, "") { return (arg % 2) == 0; }Defines a matcher IsEven() to match an even number. MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; } Defines a macher IsDivisibleBy(n) to match a number divisible by n. MATCHER_P2(IsBetween, a, b, std::string(negation ? "isn't" : "is") + " between " + PrintToString(a) + " and " + PrintToString(b)) { return a <= arg && arg <= b; } Defines a matcher IsBetween(a, b) to match a value in the range [ab].

筆記:

  1. MATCHER *宏不能在函數或類中運用。
  2. 婚配器主體必需是純功用性的(即它不能有任何反作用,並且後果必需不依賴於被婚配的值和婚配器參數之外的任何東西)。
  3. 您可以運用PrintToString(x)將任何類型的值x轉換為字符串。

14. 婚配作為測試斷言

ASSERT_THAT(expression, m)Generates a fatal failure if the value of expression doesn't match matcher m. EXPECT_THAT(expression, m) Generates a non-fatal failure if the value of expression doesn't match matcher m.

六、舉措Actions

操作指定了mock函數在調用時應該執行的操作。

1. 前往值

Return()Return from a void mock function. Return(value) Return value. If the type of value is different to the mock function's return type, value is converted to the latter type at the time the expectation is set, not when the action is executed. ReturnArg<N>() Return the N-th (0-based) argument. ReturnNew<T>(a1, ..., ak) Return new T(a1, ..., ak); a different object is created each time. ReturnNull() Return a null pointer. ReturnPointee(ptr) Return the value pointed to by ptr. ReturnRef(variable) Return a reference to variable. ReturnRefOfCopy(value) Return a reference to a copy of value; the copy lives as long as the action.

2. 反作用(Side Effects)

Assign(&variable, value)Assign value to variable. DeleteArg<N>() Delete the N-th (0-based) argument, which must be a pointer. SaveArg<N>(pointer) Save the N-th (0-based) argument to *pointer. SaveArgPointee<N>(pointer) Save the value pointed to by the N-th (0-based) argument to *pointer. SetArgReferee<N>(value) Assign value to the variable referenced by the N-th (0-based) argument. SetArgPointee<N>(value) Assign value to the variable pointed by the N-th (0-based) argument. SetArgumentPointee<N>(value) Same as SetArgPointee<N>(value). Deprecated. Will be removed in v1.7.0. SetArrayArgument<N>(first, last) Copies the elements in source range [firstlast) to the array pointed to by the N-th (0-based) argument, which can be either a pointer or an iterator. The action does not take ownership of the elements in the source range. SetErrnoAndReturn(error, value) Set errno to error and return value. Throw(exception) Throws the given exception, which can be any copyable value. Available since v1.1.0.

3. 運用函數或函子作為舉措Using a Function or a Functor as an Action

Invoke(f)Invoke f with the arguments passed to the mock function, where f can be a global/static function or a functor. Invoke(object_pointer, &class::method) Invoke the {method on the object with the arguments passed to the mock function. InvokeWithoutArgs(f) Invoke f, which can be a global/static function or a functor. f must take no arguments. InvokeWithoutArgs(object_pointer, &class::method) Invoke the method on the object, which takes no arguments. InvokeArgument<N>(arg1, arg2, ..., argk) Invoke the mock function's N-th (0-based) argument, which must be a function or a functor, with the k arguments.

被調用函數的前往值被用作舉措的前往值。
定義要與Invoke *()一同運用的函數或函數時,可以將任何未運用的參數聲明為未運用:

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

在Invoke Argument <N>(...)中,假如一個參數需求經過援用傳遞,則將其包裝在ByRef()中。 例如,

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

調用模仿函數#2參數,經過值傳遞給它5和字符串(“Hi”),並經過援用傳遞foo。

Default Action

DoDefault()Do the default action (specified by ON_CALL() or the built-in one).

Note: due to technical reasons, DoDefault() cannot be used inside a composite action - trying to do so will result in a run-time error.

Composite Actions

DoAll(a1, a2, ..., an)Do all actions a1 to an and return the result of an in each invocation. The first n - 1sub-actions must return void. IgnoreResult(a) Perform action a and ignore its result. a must not return void. WithArg<N>(a) Pass the N-th (0-based) argument of the mock function to action a and perform it. WithArgs<N1, N2, ..., Nk>(a) Pass the selected (0-based) arguments of the mock function to action a and perform it. WithoutArgs(a) Perform action a without any arguments.

Defining Actions

ACTION(Sum) { return arg0 + arg1; }Defines an action Sum() to return the sum of the mock function's argument #0 and #1. ACTION_P(Plus, n) { return arg0 + n; } Defines an action Plus(n) to return the sum of the mock function's argument #0 and n. ACTION_Pk(Foo, p1, ..., pk) { statements; } Defines a parameterized action Foo(p1, ..., pk) to execute the given statements.

The ACTION* macros cannot be used inside a function or class.

七、Cardinalities基數

這些在Times()中用於指定將調用模仿函數的次數:

AnyNumber()The function can be called any number of times. AtLeast(n) The call is expected at least n times. AtMost(n) The call is expected at most n times. Between(m, n) The call is expected between m and n (inclusive) times. Exactly(n) or n The call is expected exactly n times. In particular, the call should never happen when n is 0.

八、希冀順序(Expectation Order)

默許狀況下,希冀可以按任何順序婚配。假如一些或一切希冀必需在給定的順序中婚配,則有兩種方式來指定它們。 它們可以獨自運用或一同運用。

1.The After Clause

using ::testing::Expectation;
...
Expectation init_x = EXPECT_CALL(foo, InitX());
Expectation init_y = EXPECT_CALL(foo, InitY());
EXPECT_CALL(foo, Bar())
    .After(init_x, init_y);

上邊說,只要在InitX()和InitY()被調用之後才干調用Bar()。

假如你不知道你寫的希冀有多少個前提條件,你可以運用ExpectationSet來搜集它們:

using ::testing::ExpectationSet;
...
ExpectationSet all_inits;
for (int i = 0; i < element_count; i++) {
  all_inits += EXPECT_CALL(foo, InitElement(i));
}
EXPECT_CALL(foo, Bar())
    .After(all_inits);

下面說,只要在一切元素都被初始化之後才干調用Bar()。(但我們不關懷哪些元素在其他元素之前被初始化)。

在 .After(all_inits)​中運用ExpectationSet之後再修正ExpectationSet不會影響.After()的含義。

2. 序列

當你有一個長鏈的順序希冀,運用序列指定順序更容易,這不需求給鏈中的每個希冀一個不同的稱號。同一序列中的一切預期調用必需按其指定的順序發作。

using ::testing::Sequence;
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()之前調用,後兩個可以以任何順序發作。

在一個序列中方便地提出許多希冀:

using ::testing::InSequence;
{
  InSequence dummy;

  EXPECT_CALL(...)...;
  EXPECT_CALL(...)...;
  ...
  EXPECT_CALL(...)...;
}

上邊說,在dummy范圍內的一切預期調用必需以嚴厲的順序發作。 稱號dummy是不相關的。)

九、驗證和重置模仿

Google Mock會在模仿對象被毀壞時驗證對模仿對象的希冀,或許您可以更早地執行:

using ::testing::Mock;
...
// Verifies and removes the expectations on mock_obj;
// returns true iff successful.
Mock::VerifyAndClearExpectations(&mock_obj);
...
// Verifies and removes the expectations on mock_obj;
// also removes the default actions set by ON_CALL();
// returns true iff successful.
Mock::VerifyAndClear(&mock_obj);

您還可以通知Google Mock模仿對象可以走漏,無需停止驗證:

Mock::AllowLeak(&mock_obj);

十、模仿類

Google Mock定義了一個方便的模仿類模板

class MockFunction<R(A1, ..., An)> {
 public:
  MOCK_METHODn(Call, R(A1, ..., An));
};

 

 

 

---恢復內容完畢---

CheatSheet文檔中包括了GMock一切常用的東西,看了這個根本上就可以用它了,本文翻譯自:https://github.com/google/googletest/blob/master/googlemock/docs/CheatSheet.md

一、定義一個模仿類

1. 模仿一個正常的類,就是接口類

  給:

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

(note that ~Foo() must be virtual) we can define its mock as,定義模仿類。

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

創立一個“nice”模仿對象疏忽一切無趣的調用,或一個“strict”模仿對象,將它們視為失敗:

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

2. 模仿一個類模板

To mock:

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

(note that ~StackInterface() must be virtual) just append _T to the MOCK_* macros:

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

3. 指定模仿函數的調用商定

假如您的mock函數不運用默許調用商定,您可以經過將_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>定義。

二、在測試中運用模仿器

典型的流程是:

  1. 導入您需求運用的Google Mock稱號。一切Google Mock稱號都位於測試命名空間中,除非它們是宏或其他正文。
  2. 創立模仿對象。
  3. (可選)設置模仿對象的默許操作。
  4. 設置你對模仿對象的希冀(他們怎樣叫?他們做什麼?)。
  5. 運用模仿對象的練習代碼;如有必要,請運用Google Test斷言反省後果。
  6. 當模仿對象被毀壞時,Google Mock會自動驗證一切對其的希冀能否滿足。

這裡是一個例子:

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

TEST(BarTest, DoesThis) {
  MockFoo foo;                                    // #2

  ON_CALL(foo, GetSize())                         // #3
      .WillByDefault(Return(1));
  // ... other default actions ...

  EXPECT_CALL(foo, Describe(5))                   // #4
      .Times(3)
      .WillRepeatedly(Return("Category 5"));
  // ... other expectations ...

  EXPECT_EQ("good", MyProductionFunction(&foo));  // #5
}                                                 // #6

三、設置默許操作

Google Mock對任何前往void,bool,數值或指針的函數都有一個內置的默許舉措。

要為全局前往類型T的函數自定義默許操作:

using ::testing::DefaultValue;

// Sets the default value to be returned. T must be CopyConstructible.
DefaultValue<T>::Set(value);
// Sets a factory. Will be invoked on demand. T must be MoveConstructible.
//   T MakeT();
DefaultValue<T>::SetFactory(&MakeT);
// ... use the mocks ...
// Resets the default value.
DefaultValue<T>::Clear();

要自定義特定辦法的默許操作,請運用ON_CALL():

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

四、設置希冀

EXPECT_CALL()在模仿辦法上設置希冀(如何調用它?它會做什麼?):

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

假如省略Times(),則基數假定為:

  • Times(1)當沒有WillOnce()和WillRepeatedly();
  • 當有n個WillOnce()但沒有WillRepeatedly()時,Times(n),其中n> = 1; 要麼
  • 當有n個WillOnce()和WillRepeatedly(),其中n> = 0時,Times(AtLeast(n))。

沒有EXPECT_CALL()的辦法可以被恣意調用屢次,並且每次都將采取默許操作。

五、婚配

婚配器婚配單個參數。 您可以在ON_CALL()或EXPECT_CALL()中運用它,或運用它直接驗證值:

EXPECT_THAT(value, matcher)Asserts that value matches matcher. ASSERT_THAT(value, matcher) The same as EXPECT_THAT(value, matcher), except that it generates a fatal failure.

內置的婚配(其中參數是函數參數)分為幾類:

1. 通配符

_argument can be any value of the correct type可以代表恣意類型. A<type>() or An<type>() argument can be any value of type可以是type類型的恣意值.

2. 普通比擬

Eq(value) 或許 value argument == value,method中的形參必需是value Ge(value) argument >= value,method中的形參必需大於等於value Gt(value) argument > value Le(value) argument <= value Lt(value) argument < value Ne(value) argument != value IsNull() method的形參必需是NULL指針 NotNull() argument is a non-null pointer Ref(variable) 形參是variable的援用 TypedEq<type>(value) 形參的類型必需是type類型,而且值必需是value。當模仿函數被重載你能夠需求它而不是Eq(vlaue)

留意** 除了Ref()之外,這些婚配器會創立一個值的正本,以備日後修正或銷毀。 假如編譯器埋怨該值沒有公共正本結構函數,請嘗試將其包裝在ByRef()中,例如。 Eq(ByRef(non_copyable_value))。 假如你這樣做,請確保non_copyable_value之後不改動,否則你的婚配器的含義將被改動。

3. 浮點數的比擬

DoubleEq(a_double) 形參是一個double類型,比方值近似於a_double,兩個NaN是不相等的 FloatEq(a_float) 同上,只不過類型是float NanSensitiveDoubleEq(a_double) 形參是一個double類型,比方值近似於a_double,兩個NaN是相等的,這個是用戶所希望的方式 NanSensitiveFloatEq(a_float) 同上,只不過形參是float

上述婚配器運用基於ULP的比擬(與Google Test中運用的比擬相反)。 它們依據希冀值的相對值自動選擇合理的誤差界線。 DoubleEq()和FloatEq()契合IEEE規范,這需求比擬兩個NaNs的相等性前往false。 NanSensitive *版本將兩個NaNs相等,這通常是用戶想要的。

DoubleNear(a_double, max_abs_error)argument is a double value close to a_double (absolute error <= max_abs_error), treating two NaNs as unequal. FloatNear(a_float, max_abs_error) argument is a float value close to a_float (absolute error <= max_abs_error), treating two NaNs as unequal. NanSensitiveDoubleNear(a_double, max_abs_error) argument is a double value close to a_double (absolute error <= max_abs_error), treating two NaNs as equal. NanSensitiveFloatNear(a_float, max_abs_error) argument is a float value close to a_float (absolute error <= max_abs_error), treating two NaNs as equal.

4. String Matchers

這裡的字符串即可以是C作風的字符串,也可以是C++作風的。

ContainsRegex(string) 形參婚配給定的正則表達式 EndsWith(suffix) 形參以suffix截尾 HasSubstr(string) 形參有string這個子串 MatchesRegex(string) 從第一個字符到最後一個字符都完全婚配給定的正則表達式. StartsWith(prefix) 形參以prefix開端 StrCaseEq(string) 參數等於string,並且疏忽大小寫 StrCaseNe(string) 參數不是string,並且疏忽大小寫 StrEq(string) 參數等於string StrNe(string) 參數不等於string

5. 容器的婚配

很多STL的容器的比擬都支持==這樣的操作,關於這樣的容器可以運用上述的Eq(expected_container)來比擬或許只是expect_container來完全婚配容器。但假如你想寫得更為靈敏,可以運用上面的這些容器婚配辦法:

ContainerEq(container)The same as Eq(container) except that the failure message also includes which elements are in one container but not the other. Contains(e) argument contains an element that matches e, which can be either a value or a matcher. Each(e) argument is a container where every element matches e, which can be either a value or a matcher. ElementsAre(e0, e1, ..., en) argument has n + 1 elements, where the i-th element matches ei, which can be a value or a matcher. 0 to 10 arguments are allowed. ElementsAreArray({ e0, e1, ..., en })ElementsAreArray(array), or ElementsAreArray(array, count) The same as ElementsAre() except that the expected element values/matchers come from an initializer list, STL-style container, or C-style array. IsEmpty() argument is an empty container (container.empty()). Pointwise(m, container) argument contains the same number of elements as in container, and for all i, (the i-th element in argument, the i-th element in container) match m, which is a matcher on 2-tuples. E.g. Pointwise(Le(), upper_bounds) verifies that each element in argument doesn't exceed the corresponding element in upper_bounds. See more detail below. SizeIs(m) argument is a container whose size matches m. E.g. SizeIs(2) or SizeIs(Lt(2)). UnorderedElementsAre(e0, e1, ..., en) argument has n + 1 elements, and under some permutation each element matches an ei (for a different i), which can be a value or a matcher. 0 to 10 arguments are allowed. UnorderedElementsAreArray({ e0, e1, ..., en })UnorderedElementsAreArray(array), or UnorderedElementsAreArray(array, count) The same as UnorderedElementsAre() except that the expected element values/matchers come from an initializer list, STL-style container, or C-style array. WhenSorted(m) When argument is sorted using the < operator, it matches container matcher m. E.g. WhenSorted(UnorderedElementsAre(1, 2, 3)) verifies that argument contains elements 12, and 3, ignoring order. WhenSortedBy(comparator, m) The same as WhenSorted(m), except that the given comparator instead of < is used to sort argument. E.g. WhenSortedBy(std::greater<int>(), ElementsAre(3, 2, 1)).

留意:

  • 這些婚配器也可以婚配:

     i. 經過援用傳遞的本地數組(例如在Foo(const int(&a)[5])中)和

     ii. 作為指針和計數傳遞的數組(例如,在Bar(const T * buffer,int len) - 參見 Multi-argument Matchers)。

  • 婚配的數組可以是多維的(即其元素可以是數組)。

  • 在Pointwise(m,...)中的m應該是:: testing :: tuple <T,U>的婚配器,其中T和U辨別是實踐容器和預期容器的元素類型。 例如,要比擬兩個Foo容器,其中Foo不支持operator ==但是有一個Equals()辦法,可以寫:

using ::testing::get;
MATCHER(FooEq, "") {
  return get<0>(arg).Equals(get<1>(arg));
}
...
EXPECT_THAT(actual_foos, Pointwise(FooEq(), expected_foos));

6. 成員婚配器

Field(&class::field, m)argument.field (or argument->field when argument is a plain pointer) matches matcher m, where argument is an object of type class. Key(e) argument.first matches e, which can be either a value or a matcher. E.g. Contains(Key(Le(5))) can verify that a map contains a key <= 5. Pair(m1, m2) argument is an std::pair whose first field matches m1 and second field matches m2. Property(&class::property, m) argument.property() (or argument->property() when argument is a plain pointer) matches matcher m, where argument is an object of type class.

7. 婚配函數或函數的後果

ResultOf(f, m)f(argument) matches matcher m, where f is a function or functor.

 8. 指針婚配

Pointee(m)

argument (either a smart pointer or a raw pointer) points to a value that matches matcher m.

WhenDynamicCastTo<T>(m)

when argument is passed through dynamic_cast<T>(), it matches matcher m.

 9. 多參數婚配器

從技術上講,完全婚配器婚配單個值。 “多參數”婚配器只是婚配元組的婚配器。 以下婚配器可用於婚配元組(x,y):

Eq()x == y Ge() x >= y Gt() x > y Le() x <= y Lt() x < y Ne() x != y

您可以運用以下選擇器來選擇參數的子集(或對其重新排序)以參與婚配:

AllArgs(m)Equivalent to m. Useful as syntactic sugar in .With(AllArgs(m)). Args<N1, N2, ..., Nk>(m) The tuple of the k selected (using 0-based indices) arguments matches m, e.g. Args<1, 2>(Eq()).

10. 復合婚配

你可以從一個或多個其他婚配器做一個婚配器:

AllOf(m1, m2, ..., mn)argument matches all of the matchers m1 to mn. AnyOf(m1, m2, ..., mn) argument matches at least one of the matchers m1 to mn. Not(m) argument doesn't match matcher m.

11. Adapters for Matchers

MatcherCast<T>(m)casts matcher m to type Matcher<T>. SafeMatcherCast<T>(m) safely casts matcher m to type Matcher<T>. Truly(predicate) predicate(argument) returns something considered by C++ to be true, where predicate is a function or functor.

12 .婚配作為謂詞(Matchers as Predicates)

Matches(m)(value)evaluates to true if value matches m. You can use Matches(m) alone as a unary functor. ExplainMatchResult(m, value, result_listener) evaluates to true if value matches m, explaining the result to result_listener. Value(value, m) evaluates to true if value matches m.

13. 定義婚配

MATCHER(IsEven, "") { return (arg % 2) == 0; }Defines a matcher IsEven() to match an even number. MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; } Defines a macher IsDivisibleBy(n) to match a number divisible by n. MATCHER_P2(IsBetween, a, b, std::string(negation ? "isn't" : "is") + " between " + PrintToString(a) + " and " + PrintToString(b)) { return a <= arg && arg <= b; } Defines a matcher IsBetween(a, b) to match a value in the range [ab].

筆記:

  1. MATCHER *宏不能在函數或類中運用。
  2. 婚配器主體必需是純功用性的(即它不能有任何反作用,並且後果必需不依賴於被婚配的值和婚配器參數之外的任何東西)。
  3. 您可以運用PrintToString(x)將任何類型的值x轉換為字符串。

14. 婚配作為測試斷言

ASSERT_THAT(expression, m)Generates a fatal failure if the value of expression doesn't match matcher m. EXPECT_THAT(expression, m) Generates a non-fatal failure if the value of expression doesn't match matcher m.

六、舉措Actions

操作指定了mock函數在調用時應該執行的操作。

1. 前往值

Return()Return from a void mock function. Return(value) Return value. If the type of value is different to the mock function's return type, value is converted to the latter type at the time the expectation is set, not when the action is executed. ReturnArg<N>() Return the N-th (0-based) argument. ReturnNew<T>(a1, ..., ak) Return new T(a1, ..., ak); a different object is created each time. ReturnNull() Return a null pointer. ReturnPointee(ptr) Return the value pointed to by ptr. ReturnRef(variable) Return a reference to variable. ReturnRefOfCopy(value) Return a reference to a copy of value; the copy lives as long as the action.

2. 反作用(Side Effects)

Assign(&variable, value)Assign value to variable. DeleteArg<N>() Delete the N-th (0-based) argument, which must be a pointer. SaveArg<N>(pointer) Save the N-th (0-based) argument to *pointer. SaveArgPointee<N>(pointer) Save the value pointed to by the N-th (0-based) argument to *pointer. SetArgReferee<N>(value) Assign value to the variable referenced by the N-th (0-based) argument. SetArgPointee<N>(value) Assign value to the variable pointed by the N-th (0-based) argument. SetArgumentPointee<N>(value) Same as SetArgPointee<N>(value). Deprecated. Will be removed in v1.7.0. SetArrayArgument<N>(first, last) Copies the elements in source range [firstlast) to the array pointed to by the N-th (0-based) argument, which can be either a pointer or an iterator. The action does not take ownership of the elements in the source range. SetErrnoAndReturn(error, value) Set errno to error and return value. Throw(exception) Throws the given exception, which can be any copyable value. Available since v1.1.0.

3. 運用函數或函子作為舉措Using a Function or a Functor as an Action

Invoke(f)Invoke f with the arguments passed to the mock function, where f can be a global/static function or a functor. Invoke(object_pointer, &class::method) Invoke the {method on the object with the arguments passed to the mock function. InvokeWithoutArgs(f) Invoke f, which can be a global/static function or a functor. f must take no arguments. InvokeWithoutArgs(object_pointer, &class::method) Invoke the method on the object, which takes no arguments. InvokeArgument<N>(arg1, arg2, ..., argk) Invoke the mock function's N-th (0-based) argument, which must be a function or a functor, with the k arguments.

被調用函數的前往值被用作舉措的前往值。
定義要與Invoke *()一同運用的函數或函數時,可以將任何未運用的參數聲明為未運用:

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

在Invoke Argument <N>(...)中,假如一個參數需求經過援用傳遞,則將其包裝在ByRef()中。 例如,

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

調用模仿函數#2參數,經過值傳遞給它5和字符串(“Hi”),並經過援用傳遞foo。

Default Action

DoDefault()Do the default action (specified by ON_CALL() or the built-in one).

Note: due to technical reasons, DoDefault() cannot be used inside a composite action - trying to do so will result in a run-time error.

Composite Actions

DoAll(a1, a2, ..., an)Do all actions a1 to an and return the result of an in each invocation. The first n - 1sub-actions must return void. IgnoreResult(a) Perform action a and ignore its result. a must not return void. WithArg<N>(a) Pass the N-th (0-based) argument of the mock function to action a and perform it. WithArgs<N1, N2, ..., Nk>(a) Pass the selected (0-based) arguments of the mock function to action a and perform it. WithoutArgs(a) Perform action a without any arguments.

Defining Actions

ACTION(Sum) { return arg0 + arg1; }Defines an action Sum() to return the sum of the mock function's argument #0 and #1. ACTION_P(Plus, n) { return arg0 + n; } Defines an action Plus(n) to return the sum of the mock function's argument #0 and n. ACTION_Pk(Foo, p1, ..., pk) { statements; } Defines a parameterized action Foo(p1, ..., pk) to execute the given statements.

The ACTION* macros cannot be used inside a function or class.

七、Cardinalities基數

這些在Times()中用於指定將調用模仿函數的次數:

AnyNumber()The function can be called any number of times. AtLeast(n) The call is expected at least n times. AtMost(n) The call is expected at most n times. Between(m, n) The call is expected between m and n (inclusive) times. Exactly(n) or n The call is expected exactly n times. In particular, the call should never happen when n is 0.

八、希冀順序(Expectation Order)

默許狀況下,希冀可以按任何順序婚配。假如一些或一切希冀必需在給定的順序中婚配,則有兩種方式來指定它們。 它們可以獨自運用或一同運用。

1.The After Clause

using ::testing::Expectation;
...
Expectation init_x = EXPECT_CALL(foo, InitX());
Expectation init_y = EXPECT_CALL(foo, InitY());
EXPECT_CALL(foo, Bar())
    .After(init_x, init_y);

上邊說,只要在InitX()和InitY()被調用之後才干調用Bar()。

假如你不知道你寫的希冀有多少個前提條件,你可以運用ExpectationSet來搜集它們:

using ::testing::ExpectationSet;
...
ExpectationSet all_inits;
for (int i = 0; i < element_count; i++) {
  all_inits += EXPECT_CALL(foo, InitElement(i));
}
EXPECT_CALL(foo, Bar())
    .After(all_inits);

下面說,只要在一切元素都被初始化之後才干調用Bar()。(但我們不關懷哪些元素在其他元素之前被初始化)。

在 .After(all_inits)​中運用ExpectationSet之後再修正ExpectationSet不會影響.After()的含義。

2. 序列

當你有一個長鏈的順序希冀,運用序列指定順序更容易,這不需求給鏈中的每個希冀一個不同的稱號。同一序列中的一切預期調用必需按其指定的順序發作。

using ::testing::Sequence;
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()之前調用,後兩個可以以任何順序發作。

在一個序列中方便地提出許多希冀:

using ::testing::InSequence;
{
  InSequence dummy;

  EXPECT_CALL(...)...;
  EXPECT_CALL(...)...;
  ...
  EXPECT_CALL(...)...;
}

上邊說,在dummy范圍內的一切預期調用必需以嚴厲的順序發作。 稱號dummy是不相關的。)

九、驗證和重置模仿

Google Mock會在模仿對象被毀壞時驗證對模仿對象的希冀,或許您可以更早地執行:

using ::testing::Mock;
...
// Verifies and removes the expectations on mock_obj;
// returns true iff successful.
Mock::VerifyAndClearExpectations(&mock_obj);
...
// Verifies and removes the expectations on mock_obj;
// also removes the default actions set by ON_CALL();
// returns true iff successful.
Mock::VerifyAndClear(&mock_obj);

您還可以通知Google Mock模仿對象可以走漏,無需停止驗證:

Mock::AllowLeak(&mock_obj);

十、模仿類

Google Mock定義了一個方便的模仿類模板

class MockFunction<R(A1, ..., An)> {
 public:
  MOCK_METHODn(Call, R(A1, ..., An));
};

 See this recipe for one application of it.

十 一、Flags

--gmock_catch_leaked_mocks=0Don't report leaked mock objects as failures. --gmock_verbose=LEVEL Sets the default verbosity level (infowarning, or error) of Google Mock messages.

十二、一個關於婚配器的例子

舉一個測試重載函數的婚配器的例子吧,覺得這個挺費事的,另外google提供了很多例子,不知道怎樣寫的時分,可以去裡邊找。

//接口類
class Foo {
public:
   virtual bool Transform() = 0;
   // Overloaded on the types and/or numbers of arguments.
   virtual int Add(char x) = 0;
   virtual int Add(int x,int y) = 0;
   virtual int Add(int times, char x) = 0;
  
protected:
	virtual void Resume() = 0;

private:
	virtual int GetTimeOut() = 0;
};

  

#include "Foo.h"
#include "gmock\gmock.h"
//模仿類
//子類修正父類的訪問權限
class MockFoo : public Foo {
public:

	MOCK_METHOD0(Transform, bool());

	// The following must be in the public section, even though the
	// methods are protected or private in the base class.
	MOCK_METHOD0(Resume, void());
	MOCK_METHOD0(GetTimeOut, int());
	//virtual int Add(char x);
	//virtual int Add(int times, char x);
	// virtual int Add(int x);
	MOCK_METHOD1(Add, int(char x));
	//MOCK_METHOD1(Add, int(int x));
	MOCK_METHOD2(Add, int(int times, char x));
	// virtual int Add(int x,int y) = 0;
	MOCK_METHOD2(Add, int(int x, int y));
};

  測試用例:

#include "stdafx.h"
using namespace std;
using ::testing::Return;
using ::testing::_;
using ::testing::An;
using ::testing::Matcher;
using ::testing::Lt;
using ::testing::TypedEq;
using ::testing::Matches;
using ::testing::Le;
using ::testing::Ne;
using ::testing::AllOf;


//測試模仿private、protected辦法:
TEST(TestMockPrivate, TestPrivate) {
  
	MockFoo foo;
	//GetTimeOut是private修飾的
	EXPECT_CALL(foo, GetTimeOut())
		.WillOnce(Return(1));

	cout << "test private GetTimeOut:" << foo.GetTimeOut() << endl; //1
}
//測試重載辦法
TEST(TestMockOverload, TestOverload) {
	MockFoo foo;

	EXPECT_CALL(foo, Add(_))
		.Times(1)
		.WillOnce(Return(1));

	cout << "test TestOverload Add:" << foo.Add('c') << endl; //1
}
//測試數量相反,類型不同的狀況。
// virtual int Add(int x,int y) = 0;
// virtual int Add(int times, char x) = 0;
TEST(TestMockOverload, TestSameNumArg) {
	MockFoo foo;
	//兩個都是int
	EXPECT_CALL(foo, Add(An<int>(), An<int>()))
		.Times(1)
		.WillOnce(Return(8));
	int c = foo.Add(3, 5);
	cout << "test TestOverload Add:" <<c<< endl; //8

	
	EXPECT_CALL(foo, Add(Matcher<int>(Lt(10)), TypedEq<char>('c')))
		.Times(1)
		.WillOnce(Return(7));
	c = foo.Add(2, 'c');
	cout << "test TestOverload Add:" << c << endl; //7
}
//測試數量相反,類型不同的狀況。
TEST(TestMockOverload, TestSameNumArg2) {
   MockFoo foo;
   EXPECT_CALL(foo, Add(Matcher<int>(Lt(5)), An<int>()))
		.Times(1)
		.WillOnce(Return(7));
	int c = foo.Add(2, 5);
	cout << "test TestOverload Add:" << c << endl; //7
	//第一個參數小於5,,第二個參數是'd'
	EXPECT_CALL(foo, Add(Matcher<int>(Lt(5)), Matcher<char>('d')))
		.Times(1)
		.WillOnce(Return(10));
	c = foo.Add(2, 'd'); //10
	cout << "test TestOverload Add:" << c << endl; //10
}
int main(int argc, char** argv) {
	::testing::InitGoogleMock(&argc, argv);

	return RUN_ALL_TESTS();
}

運轉後果:可以看到都成功啦

 

ok。。完畢。。

轉載請注明出處:http://www.cnblogs.com/jycboy/p/gmock_cheatsheet.html

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved