Google Test 快速参考

断言

ASSERT_* versions generate fatal failures when they fail, and abort the current function.
EXPECT_* versions generate nonfatal failures, which don’t abort the current function.

Fatal assertionNonfatal assertionVerifies
ASSERT_TRUE(condition);EXPECT_TRUE(condition);condition is true
ASSERT_FALSE(condition);EXPECT_FALSE(condition);condition is false
ASSERT_EQ(val1, val2);EXPECT_EQ(val1, val2);val1 == val2
ASSERT_NE(val1, val2);EXPECT_NE(val1, val2);val1 != val2
ASSERT_LT(val1, val2);EXPECT_LT(val1, val2);val1 < val2
ASSERT_LE(val1, val2);EXPECT_LE(val1, val2);val1 <= val2
ASSERT_GT(val1, val2);EXPECT_GT(val1, val2);val1 > val2
ASSERT_GE(val1, val2);EXPECT_GE(val1, val2);val1 >= val2
ASSERT_STREQ(str1,str2);EXPECT_STREQ(str1,str2);the two C strings have the same content
ASSERT_STRNE(str1,str2);EXPECT_STRNE(str1,str2);the two C strings have different contents
ASSERT_STRCASEEQ(str1,str2);EXPECT_STRCASEEQ(str1,str2);the two C strings have the same content, ignoring case
ASSERT_STRCASENE(str1,str2);EXPECT_STRCASENE(str1,str2);the two C strings have different contents, ignoring case

You can use EXPECT_NE(nullptr, ptr) and ASSERT_NE(nullptr, ptr).
Googletest support EXPECT_EQ(NULL, ptr) and ASSERT_EQ(NULL, ptr), but not EXPECT_NE(NULL, ptr) and ASSERT_NE(NULL, ptr).
EXPECT_TRUE(ptr != NULL) works just as well.

TEST

int Factorial(int n);  // Returns the factorial of n
// Tests factorial of 0.
TEST(FactorialTest, HandlesZeroInput) {
  EXPECT_EQ(Factorial(0), 1);
}

// Tests factorial of positive numbers.
TEST(FactorialTest, HandlesPositiveInput) {
  EXPECT_EQ(Factorial(1), 1);
  EXPECT_EQ(Factorial(2), 2);
  EXPECT_EQ(Factorial(3), 6);
  EXPECT_EQ(Factorial(8), 40320);
}

Test suite names and test names should not contain underscore.

TEST_F(Test Fixtures)

template <typename E>  // E is the element type.
class Queue {
 public:
  Queue();
  void Enqueue(const E& element);
  E* Dequeue();  // Returns NULL if the queue is empty.
  size_t size() const;
  ...
};
class QueueTest : public ::testing::Test {
 protected:
  void SetUp() override {
     q1_.Enqueue(1);
     q2_.Enqueue(2);
     q2_.Enqueue(3);
  }

  // void TearDown() override {}

  Queue<int> q0_;
  Queue<int> q1_;
  Queue<int> q2_;
};

To create a fixture:

  1. Derive a class from ::testing::Test. Start its body with protected:, as
    we’ll want to access fixture members from sub-classes.
  2. Inside the class, declare any objects you plan to use.
  3. If necessary, write a default constructor or SetUp() function to prepare
    the objects for each test. A common mistake is to spell SetUp() as
    Setup() with a small u - Use override in C++11 to make sure you
    spelled it correctly.
  4. If necessary, write a destructor or TearDown() function to release any
    resources you allocated in SetUp().
  5. If needed, define subroutines for your tests to share.
TEST_F(QueueTest, IsEmptyInitially) {
  EXPECT_EQ(q0_.size(), 0);
}

TEST_F(QueueTest, DequeueWorks) {
  int* n = q0_.Dequeue();
  EXPECT_EQ(n, nullptr);

  n = q1_.Dequeue();
  ASSERT_NE(n, nullptr);
  EXPECT_EQ(*n, 1);
  EXPECT_EQ(q1_.size(), 0);
  delete n;

  n = q2_.Dequeue();
  ASSERT_NE(n, nullptr);
  EXPECT_EQ(*n, 2);
  EXPECT_EQ(q2_.size(), 1);
  delete n;
}

main()

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

gMock

Wrap the API in an interface (say, Turtle):

class Turtle {
  ...
  virtual ~Turtle() {};
  virtual void PenUp() = 0;
  virtual void PenDown() = 0;
  virtual void Forward(int distance) = 0;
  virtual void Turn(int degrees) = 0;
  virtual void GoTo(int x, int y) = 0;
  virtual int GetX() const = 0;
  virtual int GetY() const = 0;
};

Writing the Mock Class

Steps you need to follow:

  • Derive a class MockTurtle from Turtle.
  • Take a virtual function of Turtle.
  • In the public: section of the child class, write MOCK_METHOD();
  • Now comes the fun part: you take the function signature, cut-and-paste it
    into the macro, and add two commas - one between the return type and the
    name, another between the name and the argument list.
  • If you’re mocking a const method, add a 4th parameter containing (const)
    (the parentheses are required).
  • Since you’re overriding a virtual method, we suggest adding the override
    keyword. For const methods the 4th parameter becomes (const, override),
    for non-const methods just (override). This isn’t mandatory.
  • Repeat until all virtual functions you want to mock are done. (It goes
    without saying that all pure virtual methods in your abstract class must
    be either mocked or overridden.)
#include "gmock/gmock.h"  // Brings in gMock.

class MockTurtle : public Turtle {
 public:
  ...
  MOCK_METHOD(void, PenUp, (), (override));
  MOCK_METHOD(void, PenDown, (), (override));
  MOCK_METHOD(void, Forward, (int distance), (override));
  MOCK_METHOD(void, Turn, (int degrees), (override));
  MOCK_METHOD(void, GoTo, (int x, int y), (override));
  MOCK_METHOD(int, GetX, (), (const, override));
  MOCK_METHOD(int, GetY, (), (const, override));
};

Using Mocks in Tests

  1. Import the gMock names from the testing namespace such that you can use
    them unqualified.
  2. Create some mock objects.
  3. Specify your expectations on them (How many times will a method be called?
    With what arguments? What should it do? etc.).
  4. Exercise some code that uses the mocks; optionally, check the result using
    googletest assertions. If a mock method is called more than expected or with
    wrong arguments, you’ll get an error immediately.
  5. When a mock is destructed, gMock will automatically check whether all
    expectations on it have been satisfied.
#include "path/to/mock-turtle.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

using ::testing::AtLeast;                         // #1

TEST(PainterTest, CanDrawSomething) {
  MockTurtle turtle;                              // #2
  EXPECT_CALL(turtle, PenDown())                  // #3
      .Times(AtLeast(1));

  Painter painter(&turtle);                       // #4

  EXPECT_TRUE(painter.DrawCircle(0, 0, 10));      // #5
}

Important note: gMock requires expectations to be set before the mock
functions are called, otherwise the behavior is undefined. In particular,
you mustn’t interleave EXPECT_CALL()s and calls to the mock functions.

General EXPECT_CALL Syntax

EXPECT_CALL() sets expectations on a mock method (How will it be called?
What will it do?):

EXPECT_CALL(mock-object, method (matchers)?)
     .With(multi-argument-matcher)  ?
     .Times(cardinality)            ?
     .InSequence(sequences)         *
     .After(expectations)           *
     .WillOnce(action)              *
     .WillRepeatedly(action)        ?
     .RetiresOnSaturation();        ?

For each item above, ? means it can be used at most once, while * means it
can be used any number of times.

The (matchers) is a comma-separated list of matchers that correspond to each
of the arguments of method, and sets the expectation only for calls of
method that matches all of the matchers.
If (matchers) is omitted, the expectation is the same as if the matchers were
set to anything matchers (for example, (_, _, _, _) for a four-arg method).

If Times() is omitted, the cardinality is assumed to be:

  • Times(1) when there is neither WillOnce() nor WillRepeatedly();
  • Times(n) when there are n WillOnce()s but no WillRepeatedly(), where
    n >= 1; or
  • Times(AtLeast(n)) when there are n WillOnce()s and a
    WillRepeatedly(), where n >= 0.

If the method is not overloaded, the macro can also be called without matchers:

EXPECT_CALL(mock_object, non-overloaded-method)
    .Times(cardinality)
    .WillOnce(action)
    .WillRepeatedly(action);

Example:

using ::testing::Return;
...
EXPECT_CALL(turtle, GetX())
    .Times(5)
    .WillOnce(Return(100))
    .WillOnce(Return(150))
    .WillRepeatedly(Return(200));

says that the turtle object’s GetX() method will be called five times, it
will return 100 the first time, 150 the second time, and then 200 every time.

Using Matchers

// Expects the turtle to move forward by 100 units.
EXPECT_CALL(turtle, Forward(100));
using ::testing::_;
...
// Expects that the turtle jumps to somewhere on the x=50 line.
EXPECT_CALL(turtle, GoTo(50, _));
using ::testing::Ge;
...
// Expects the turtle moves forward by at least 100.
EXPECT_CALL(turtle, Forward(Ge(100)));
// Expects the turtle to move forward.
EXPECT_CALL(turtle, Forward);
// Expects the turtle to jump somewhere.
EXPECT_CALL(turtle, GoTo);

For more details, see gMock Cheat Sheet.

Ordered Calls

using ::testing::InSequence;
...
TEST(FooTest, DrawsLineSegment) {
  ...
  {
    InSequence seq;

    EXPECT_CALL(turtle, PenDown());
    EXPECT_CALL(turtle, Forward(100));
    EXPECT_CALL(turtle, PenUp());
  }
  Foo();
}

By creating an object of type InSequence, all expectations in its scope are
put into a sequence and have to occur sequentially.

Sticky Expectations

Expectations in gMock are “sticky” by default, in the sense that they remain active even after we have reached their invocation upper bounds.

using ::testing::_;
using ::testing::AnyNumber;
...
EXPECT_CALL(turtle, GoTo(_, _))  // #1
     .Times(AnyNumber());
EXPECT_CALL(turtle, GoTo(0, 0))  // #2
     .Times(2);

This test that the turtle is asked to go to the origin exactly twice.

using ::testing::Return;
...
for (int i = n; i > 0; i--) {
  EXPECT_CALL(turtle, GetX())
      .WillOnce(Return(10*i))
      .RetiresOnSaturation();
}

RetiresOnSaturation() is to explicitly say that the expectations are not sticky.

Or make the order explicit using a sequence:

using ::testing::InSequence;
using ::testing::Return;
...
{
  InSequence s;

  for (int i = 1; i <= n; i++) {
    EXPECT_CALL(turtle, GetX())
        .WillOnce(Return(10*i))
        .RetiresOnSaturation();
  }
}

By the way, the other situation where an expectation may not be sticky is when
it’s in a sequence - as soon as another expectation that comes after it in the
sequence has been used, it automatically retires (and will never be used to
match any call).

NaggyMock, NiceMock and StrictMock

TEST(...) {
  MockFoo mock_foo;
  EXPECT_CALL(mock_foo, DoThis());
  ... code that uses mock_foo ...
}

A mock object is currently naggy by default.
If a method of mock_foo other than DoThis() is called, you will get a warning.

Use NiceMock<MockFoo> instead, you can suppress the warning:

using ::testing::NiceMock;

TEST(...) {
  NiceMock<MockFoo> mock_foo;
  EXPECT_CALL(mock_foo, DoThis());
  ... code that uses mock_foo ...
}

The usage of StrictMock is similar, except that it makes all uninteresting calls failures.

Reference

[1]Googletest Primer
[2]gMock for Dummies
[3]gMock Cookbook
[4]gMock Cheat Sheet

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值