Oracle VM virtualbox+gtest文档

1.放大屏幕

然后重启,view->virtual screen 调分辨率

参考:将VirtualBox虚拟机电脑屏幕填满全屏的方法_virtualbox 全屏-CSDN博客

2.gtest文档

1.        GoogleTest Prinmer && Advanced Topics
1.框架
#include "this/package/foo.h"

#include <gtest/gtest.h>

namespace my {
namespace project {
namespace {

// The fixture for testing class Foo.
class FooTest : public testing::Test {
 protected:
  // You can remove any or all of the following functions if their bodies would
  // be empty.

  FooTest() {
     // You can do set-up work for each test here.
  }

  ~FooTest() override {
     // You can do clean-up work that doesn't throw exceptions here.
  }

  // If the constructor and destructor are not enough for setting up
  // and cleaning up each test, you can define the following methods:

  void SetUp() override {
     // Code here will be called immediately after the constructor (right
     // before each test).
  }

  void TearDown() override {
     // Code here will be called immediately after each test (right
     // before the destructor).
  }

  // Class members declared here can be used by all tests in the test suite
  // for Foo.
};

// Tests that the Foo::Bar() method does Abc.
TEST_F(FooTest, MethodBarDoesAbc) {
  const std::string input_filepath = "this/package/testdata/myinputfile.dat";
  const std::string output_filepath = "this/package/testdata/myoutputfile.dat";
  Foo f;
  EXPECT_EQ(f.Bar(input_filepath, output_filepath), 0);
}

// Tests that Foo does Xyz.
TEST_F(FooTest, DoesXyz) {
  // Exercises the Xyz feature of Foo.
}

}  // namespace
}  // namespace project
}  // namespace my

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

InitGoogleTest()函数解析GoogleTest标志的命令行,并删除所有识别的标志。这允许用户通过各种标志控制测试程序的行为。

2.使用 EXPECT_PRED 和 ASSERT_PRED 宏来验证一个简单的函数是否正确返回布尔值。
#include <gtest/gtest.h>

// 假设 IsEven 函数已经定义,并正确实现了
bool IsEven(int number) {
  return (number % 2) == 0;
}

class TestFixture : public testing::Test {
 protected:
  void SetUp() override {
    // 初始化测试环境
  }

  void TearDown() override {
    // 清理测试环境
  }
};

TEST_F(TestFixture, TestIsEven) {
  EXPECT_PRED(IsEven, 2);  // 验证 2 是偶数
  EXPECT_PRED(IsEven, 4);  // 验证 4 是偶数
  EXPECT_PRED(IsEven, 8);  // 验证 8 是偶数
  EXPECT_PRED(IsEven, 0);  // 验证 0 是偶数
  EXPECT_PRED(IsEven, -2); // 验证 -2 是偶数

  ASSERT_PRED(IsEven, 3);  // 验证 3 不是偶数,这将导致测试失败
  ASSERT_PRED(IsEven, 5);  // 验证 5 不是偶数,这将导致测试失败
}

int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
3.使用AssertionResult object断言函数返回值
testing::AssertionResult IsEven(int n) {
  if ((n % 2) == 0)
    return testing::AssertionSuccess() << n << " is even";
  else
    return testing::AssertionFailure() << n << " is odd";
}



判断:
EXPECT_FALSE(IsEven(Fib(6)))


结果:
  Value of: IsEven(Fib(6))
     Actual: true (8 is even)
  Expected: false
4.float:如果您发现EXPECT_PRED*生成的默认消息EXPECT_TRUE不满意,或者谓词的某些参数不支持流式传输到ostream,您可以改为使用谓词-格式化程序EXPECT_PRED_FORMAT* 断言。
5.EXPECT_THAT 和 ASSERT_THAT 宏用于执行复杂的断言,string的子字符串、前缀、后缀、正则表达式
6.Windows HRESULT assertions
7.Type Assertions

必须实例化

::testing::StaticAssertTypeEq<T1, T2>();


应用
template <typename T> class Foo {
 public:
  void Bar() { testing::StaticAssertTypeEq<int, T>(); }
};

测试:
void Test1() { Foo<bool> foo; }

不会报错,因为没有实例化,
只有在 Test2() 函数中调用 foo.Bar() 时,Foo<bool>::Bar() 函数才会被实例化

正确:
void Test2() { Foo<bool> foo; foo.Bar(); }
8.非致命断言和致命断言

构造函数和析构函数不被视为无效返回函数,因此您可能不会在其中使用致命断言;如果需要在构造函数或析构函数中处理错误情况,您可以调用 abort() 函数来停止整个测试执行,或者将致命断言放在测试夹具的 SetUp() 或 TearDown() 函数中。

  • 非致命断言(如 EXPECT_ 系列)可以用于任何返回类型的函数。
  • 致命断言(如 ASSERT_ 系列)只能用于返回 void 的函数。因为它们在断言失败时会立即停止测试的执行。如果致命断言被用于返回非 void 类型的函数,那么当断言失败时,返回值将不会被使用,这可能会导致编译错误,因为编译器期望一个有效的返回值。
9.GTEST_SKIP() 宏来跳过测试的执行
10.打印value    

AbslStringify() 用于将值转换为字符串形式,以便在测试断言失败时打印出来。

         PrintTo() 函数:用于自定义类型的打印。

         ::testing::PrintToString() 用于手动使用 GoogleTest 的值打印器打印一个值,返回一个 std::string

11.Death Test
  1. SSERT_DEATH():用于测试代码段在执行时是否会导致程序崩溃。
  2. EXPECT_EXIT():用于测试函数调用在执行时是否会导致程序以预期的退出状态退出。

死亡测试只关心三件事:

  • 语句是否会导致进程崩溃或退出?
  • 退出状态是否满足谓词?
  • 标准错误输出是否与匹配器匹配?
12.Regular Expression Syntax
13.Death Tests And Threads

死亡测试样式分为两种:线程安全(threadsafe)和快速(fast)。用于保证线程安全性。

14.SCOPED_TRACE()用于在多个地方调用一个子程序时跟踪错误出现在哪里
15.Propagating Fatal Failures

由于使用 ASSERT_* 和 FAIL* 宏时,当它们失败时,它们只会终止当前函数,而不是整个测试。可能会导致段错误。

16.RecordProperty 函数用于记录与测试相关的额外信息。这可以是任何有用的调试信息,例如测试执行的环境设置、测试运行的时间、测试使用的资源等。
17.同一测试套件(test suite)中的多个测试之间共享资源

        在测试夹具里定义一个static测试套件设置和清理共享资源

#include <gtest/gtest.h>

// 假设我们有一个昂贵的资源,我们需要为整个测试套件共享它
class ExpensiveResource {
public:
  ExpensiveResource() {
    // 初始化昂贵的资源
  }

  ~ExpensiveResource() {
    // 清理昂贵的资源
  }
};

// 测试夹具类,用于管理昂贵的资源
class ResourceTestFixture : public testing::Test {
 protected:
  // 声明一个静态成员变量来持有昂贵的资源
  static ExpensiveResource* shared_resource_;

  // 测试套件设置函数
  static void SetUpTestSuite() {
    shared_resource_ = new ExpensiveResource();
  }

  // 测试套件清理函数
  static void TearDownTestSuite() {
    delete shared_resource_;
    shared_resource_ = nullptr;
  }
};

// 定义静态成员变量
ExpensiveResource* ResourceTestFixture::shared_resource_ = nullptr;

// 测试用例,使用共享资源
TEST_F(ResourceTestFixture, UseSharedResource) {
  // 每个测试都可以使用 shared_resource_
  // 例如,假设 shared_resource_ 有一个方法可以执行某种操作
  shared_resource_->performOperation();
}

// 另一个测试用例,也使用共享资源
TEST_F(ResourceTestFixture, AnotherUseOfSharedResource) {
  // 每个测试都可以使用 shared_resource_
  // 例如,假设 shared_resource_ 有一个方法可以执行另一种操作
  shared_resource_->performAnotherOperation();
}

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

类似于shared_ptr

18.全局设置和清理(Global Set-Up and Tear-Down)

        假设有一个测试套件,其中包含多个测试用例,这些测试用例都需要访问一个昂贵的资源。为了高效地使用这个资源,可以定义一个测试环境类,并在其中管理这个资源

19.编写值参数化测试

一个参数测试多个实例

#include <gtest/gtest.h>
/定义一个测试夹具类
// 测试夹具类,派生自 TestWithParam<int>
class SquareTest : public testing::TestWithParam<int> {
 protected:
  // 每个测试都会调用这个函数,传递参数
  void TestBody() override {
    EXPECT_EQ(foo.ComputeSquare(GetParam()), GetParam() * GetParam());
  }
};

//TEST_P 宏定义两个测试模式,分别用于测试函数的正方形计算和负数输入。
TEST_P(SquareTest, ComputeSquarePositive) {
  // 测试正数输入
  EXPECT_EQ(foo.ComputeSquare(GetParam()), GetParam() * GetParam());
}

TEST_P(SquareTest, ComputeSquareNegative) {
  // 测试负数输入
  EXPECT_EQ(foo.ComputeSquare(GetParam()), GetParam() * GetParam());
}

//使用 INSTANTIATE_TEST_SUITE_P 宏实例化测试套件,并为它指定一系列参数值。
constexpr int kTestValues[] = {1, 2, 3, -1, -2, -3};
INSTANTIATE_TEST_SUITE_P(SquareTests,
                         SquareTest,
                         testing::ValuesIn(kTestValues));

20.Creating Value-Parameterized Abstract Tests

将值参数化测试定义在库中,并让其他人稍后实例化它们。这种模式被称为抽象测试。

步骤:

1.将参数化测试夹具类的定义放在一个头文件中,例如 foo_param_test.h

2.TEST_P 定义放在 foo_param_test.cc 文件中

21.Specifying Names for Value-Parameterized Test Parameters

第三个参数不是输入测试的参数吗,为什么用于自定义的测试名称?

22.Typed Tests

对不同类型重复相同的测试逻辑。用模板来实现

23.测试私有代码

1.将私有代码移动到名为 foo::internal 的命名空间中,其中 foo 是您的项目通常使用的命名空间,并将私有声明放在一个名为 *-internal.h 的文件中。

2.生产和测试 .cc 文件允许包含这个内部头文件

3.将您的测试夹具声明为该类的友元对象

FRIEND_TEST(TestSuiteName, TestName);

如果您希望测试夹具和测试是类的友好对象,那么它们必须定义在完全相同的命名空间中(不允许匿名或内联命名空间)

24.“Catching” Failures
 EXPECT_FATAL_FAILURE(statement, substring);
 EXPECT_FATAL_FAILURE(statement, substring);
25.Registering tests programmatically

TEST 宏处理了绝大多数的使用场景,但在某些情况下,需要运行时注册逻辑。对于这些情况,框架提供了 ::testing::RegisterTest 函数,允许调用者以动态方式注册任意测试。

26.Getting the Current Test’s Name

TestInfo 类包含正在运行的测试的名称、测试套件的名称、测试的文件位置和行号等。

要获取当前运行测试的 TestInfo 对象,要调用 current_test_info() 在 UnitTest 单例对象上:

// 获取有关当前运行测试的信息。
// 不要删除返回的对象 - 它由 UnitTest 类管理。
const testing::TestInfo* const test_info =
    testing::UnitTest::GetInstance()->current_test_info();

printf("We are in test %s of test suite %s.\n",
       test_info->name(),
       test_info->test_suite_name());
27.Extending GoogleTest by Handling Test Events

1.Defining Event Listeners

GoogleTest 提供了一个事件监听器 API,可以使用此 API 来增强或替换标准控制台输出、替换 XML 输出,或提供完全不同的输出形式,例如 GUI 或数据库。还可以使用测试事件作为检查点来实现资源泄漏检查器等。

通过重写了 OnTestStart()OnTestPartResult() 和 OnTestEnd() 方法,实现自定义

2.Using Event Listeners

3.对于OnTestPartResult() 的监听器不允许生成任何失败。

28.Running Test Programs: Advanced Options

可以通过环境变量和/或命令行标志来影响测试程序行为。

1.'*' (matches any string)

'?' (matches any single character).

'*-NegativePatterns' can be also written as '-NegativePatterns'.

For example:

  • ./foo_test Has no flag, and thus runs all its tests.
  • ./foo_test --gtest_filter=* Also runs everything, due to the single match-everything * value.
  • ./foo_test --gtest_filter=FooTest.* Runs everything in test suite FooTest .
  • ./foo_test --gtest_filter=*Null*:*Constructor* Runs any test whose full name contains either "Null" or "Constructor" .
  • ./foo_test --gtest_filter=-*DeathTest.* Runs all non-death tests.
  • ./foo_test --gtest_filter=FooTest.*-FooTest.Bar Runs everything in test suite FooTest except FooTest.Bar.
  • ./foo_test --gtest_filter=FooTest.*:BarTest.*-FooTest.Bar:BarTest.Foo Runs everything in test suite FooTest except FooTest.Bar and everything in test suite BarTest except BarTest.Foo.

Stop test execution upon first failure:--gtest_fail_fast

2.Repeating the Tests

对于一个测试结果不稳定。也许它只会在 1% 的时间内失败,

1.--gtest_repeat 标志允许您多次重复(或选择)程序中的所有(或部分)测试方法。希望,一个不可靠的测试最终会失败。

$ foo_test --gtest_repeat=1000
重复运行 foo_test 1000 次,并在失败时继续运行。

$ foo_test --gtest_repeat=-1
负数计数意味着无限重复。

$ foo_test --gtest_repeat=1000 --gtest_break_on_failure
重复运行 foo_test 1000 次,在第一次失败时停止。
这对于在调试器下运行时尤其有用:当测试失败时,它将进入调试器,然后您可以检查变量和堆栈。

$ foo_test --gtest_repeat=1000 --gtest_filter=FooBar.*
重复与过滤器匹配的测试 1000 次。


 --gtest_recreate_environments_when_repeating=false 避免重复全局设置/清理

2.设置 GTEST_REPEAT 环境变量来指定重复计数。

3.Shuffling the Tests

指定 --gtest_shuffle 标志(或通过将 GTEST_SHUFFLE 环境变量设置为 1)来以随机顺序运行测试程序中的测试。

设置--gtest_random_seed=SEED 标志(或设置 GTEST_RANDOM_SEED 环境变量),其中 SEED 是 [0, 99999] 范围内的整数,自定义随机性。

4.Distributing Test Functions to Multiple Machines

有多个可以运行测试程序的机器,希望并行运行测试函数以更快地获得结果。

TEST(A, V)
TEST(A, W)
TEST(B, X)
TEST(B, Y)
TEST(B, Z)
Suppose you have 3 machines at your disposal. To run the test functions in parallel, you would set GTEST_TOTAL_SHARDS to 3 on all machines, and set GTEST_SHARD_INDEX to 0, 1, and 2 on the machines respectively. Then you would run the same foo_test on each machine.

GoogleTest reserves the right to change how the work is distributed across the shards, but here’s one possible scenario:

Machine #0 runs A.V and B.X.
Machine #1 runs A.W and B.Y.
Machine #2 runs B.Z.

3.Controlling Test Output

1.Colored Terminal Output

2.Suppressing test passes

       仅显示测试失败,运行测试程序--gtest_brief=1,或将GTEST_BRIEF环境变量设置为1

3.Suppressing the Elapsed Time

       禁止打印每个测试的运行时间。请运行测试程序时使用 --gtest_print_time=0 命令行标志,或者将 GTEST_PRINT_TIME 环境变量设置为 0

4.Suppressing UTF-8 Text Output

运行测试程序时使用 --gtest_print_utf8=0,或者将 GTEST_PRINT_UTF8 环境变量设置为 0 来禁用 UTF-8 文本输出。

5.Generating an XML Report

设置 GTEST_OUTPUT 环境变量或使用 --gtest_output 标志,将字符串设置为 “xml:path_to_output_file”,要生成 XML 报告到指定的目录(例如,在 Linux 上为 “xml:output/directory/”)

2.Mocking

1.框架

// turtle.h
#ifndef TURTLE_H
#define TURTLE_H

#include <vector>

class Turtle {
public:
  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 int GetY() const = 0;
};

#endif // TURTLE_H

// turtle.cc
#include "turtle.h"

class Turtle : public Turtle {
public:
  void PenUp() override { pen_up_count_++; }
  void PenDown() override { pen_down_count_++; }
  void Forward(int distance) override { forward_count_++; }
  void Turn(int degrees) override { turn_count_++; }
  void GoTo(int x, int y) override { x_position_ = x; y_position_ = y; }
  int GetX() const override { return x_position_; }
  int GetY() const override { return y_position_; }

  int pen_up_count_ = 0;
  int pen_down_count_ = 0;
  int forward_count_ = 0;
  int turn_count_ = 0;
  int x_position_ = 0;
  int y_position_ = 0;
};

// mock-turtle.h
#ifndef MOCK_TURTLE_H
#define MOCK_TURTLE_H

#include "turtle.h"
#include <gmock/gmock.h>

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

#endif // MOCK_TURTLE_H

// main.cc
#include "mock-turtle.h"
#include "turtle.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>

using ::testing::Return;
using ::testing::AtLeast;

class PainterTest : public testing::Test {
protected:
  MockTurtle mock_turtle_;
};

TEST_F(PainterTest, CanDrawSomething) {
  EXPECT_CALL(mock_turtle_, PenDown())
      .Times(AtLeast(1));

  Painter painter(&mock_turtle_);
  painter.DrawCircle(0, 0, 10);
}

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

2.设置期望

EXPECT_CALL(turtle, Forward(Ge(100)));

预测:设置匹配器参数,调用的次数,调用的返回值,

多个期望会按照期望被定义的相反顺序搜索期望,用InSequence对象类指定调用的顺序

using ::testing::_;
using ::testing::Return;

class MockTurtle {
public:
  MOCK_METHOD(void, Forward, (int distance), (override));
};

TEST(TurtleTest, ForwardMethodCalls) {
  MockTurtle turtle;

  EXPECT_CALL(turtle, Forward(10));  // #1
  EXPECT_CALL(turtle, Forward(20));  // #2

  turtle.Forward(10); // 调用 Forward(10)
  turtle.Forward(20); // 调用 Forward(20)
  turtle.Forward(30); // 调用 Forward(30)
}

对于不感兴趣的调用,不去做任何申明。

3..Creating Mock Classes

MOCK_METHOD 宏来生成模拟方法

4.Dealing with unprotected commas

1.用括号包围

2.define an alias

5.Mocking Private or Protected Methods

即使方法在基类 中是受保护的或私有的,它们也必须在模拟类 的公共部分中定义。

6.Mocking Overloaded Methods

7.Mocking Non-virtual Methods

8.Mocking Free Functions

     用一个接口实现,在类外重写函数

9.Simplifying the Interface without Breaking Existing Code

通过定义一个新的模拟方法,参数列表被修剪,我们使模拟类更易于使用

10.Alternative to Mocking Concrete Classes

11.Delegating Calls to a Fake

委托中可以测试一个大类中的一些方法

12.Delegating Calls to a Real Object

13.Delegating Calls to a Parent Class

可以调用父类的非纯虚方法

14.Using Matchers

1.匹配参数值的精确匹配
  EXPECT_CALL(foo, DoThis(5))
      .WillOnce(Return('a'));
  EXPECT_CALL(foo, DoThat("Hello", bar));
2.使用简单匹配器
  EXPECT_CALL(foo, DoThis(Ge(5)))  // 参数必须 >= 5。
      .WillOnce(Return('a'));
  EXPECT_CALL(foo, DoThat("Hello", NotNull()));
      // 第二个参数不能为 NULL。
  EXPECT_CALL(foo, DoThat(_, NotNull()));
    //匹配器 _,它可以匹配任何东西:
3.组合匹配器
可以使用现有的匹配器来构建复杂的匹配器,使用 AllOf(), AllOfArray(), AnyOf(), AnyOfArray() 和 Not():
 // 参数必须 > 5 且 != 10。
  EXPECT_CALL(foo, DoThis(AllOf(Gt(5),
                                Ne(10))));

  // 第一个参数必须不包含子字符串 "blah"。
  EXPECT_CALL(foo, DoThat(Not(HasSubstr("blah")),
                          NULL));
4.匹配器是函数对象,并且参数化的匹配器可以像任何其他函数一样组合。然而,由于它们的类型可能很长,并且很少提供有意义的信息,因此使用 C++14 泛型 lambda 来避免指定类型可能更容易表达它们。
using ::testing::Contains;
using ::testing::Property;

inline constexpr auto HasFoo = [](const auto& f) {
  return Property("foo", &MyClass::foo, Contains(f));
};
...
  EXPECT_THAT(x, HasFoo("blah"));
//使用泛型 lambda 表达复杂的匹配器,断言对象 x 的 foo 属性包含字符串 "blah"。如果 x 的 foo 属
//性确实包含 "blah"。

5.类型匹配
SafeMatcherCast<T>(m) , MatcherCast<T>(m),将m转化为T类型

6.利用匹配器Selecting Between Overloaded Functions
7.Performing Different Actions Based on the Arguments
8.Matching Multiple Arguments as a Whole
  EXPECT_CALL(foo, Blah)
      .With(AllOf(Args<0, 1>(Lt()), Args<1, 2>(Lt())));
8.Using Predicates as Matchers
    using ::testing::Truly;

int IsEven(int n) { return (n % 2) == 0 ? 1 : 0; }
...
  // Bar() must be called with an even number.
  EXPECT_CALL(foo, Bar(Truly(IsEven)));
9.Matching Arguments that Are Not Copyable
    using ::testing::Eq;
using ::testing::Lt;
...
  // Expects that Foo()'s argument == bar.
  EXPECT_CALL(mock_obj, Foo(Eq(std::ref(bar))));

  // Expects that Foo()'s argument < bar.
  EXPECT_CALL(mock_obj, Foo(Lt(std::ref(bar))));
10.Validating a Member of an Object
    Field() and Property()
11.验证指针参数所指向的值
    Pointee()
12.定义自定义匹配器类
13.匹配容器
      absl::flat_hash_map<string, int> m = {{"a", 1}, {"b", 2}, {"c", 3}};
      EXPECT_THAT(m, UnorderedElementsAre(
      Pair("a", 1), Pair("b", 2), Pair("c", 3)));
14.Sharing Matchers
    多次使用同一匹配器

15.Setting Expectations

1.ON_CALL比EXPECT_CALL约束更少

2.Ignoring Uninteresting Calls

不做声明

3.Disallowing Unexpected Calls

列出所有预期的调用,不允许其他调用

4.Ignoring Uninteresting Arguments

区分调用方法次数错误与调用时使用错误参数。

5.Expecting Ordered Calls

InSequence

6.Expecting Partially Ordered Calls

7.Controlling When an Expectation Retires

EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #2 .RetiresOnSaturation();

16.Using Actions

1.Returning References from Mock Methods

2.Returning References from Mock Methods

3.Combining Actions

4.Verifying Complex Arguments

单独验证每个参数,从而更容易地诊断问题。

5.Mocking Side Effects

6.Changing a Mock Object’s Behavior Based on the State

7.Setting the Default Value for a Return Type

8.Setting the Default Actions for a Mock Method

也许您有两个具有相同返回类型的模拟方法,您希望它们具有不同的行为。

9.Using Functions/Methods/Functors/Lambdas as Actions

10.Using Functions with Extra Info as Actions

11.Invoking a Function/Method/Functor/Lambda/Callback Without Arguments

12.Invoking an Argument of the Mock Function

13.Ignoring an Action’s Result

14.Selecting an Action’s Arguments

15.Controlling How Much Information gMock Prints

16.Gaining Super Vision into Mock Calls

17.Running Tests in Emacs

2.Extending gMock

1.Writing New Matchers Quickly

自定义错误输出,打印附加信息,参数类型

2.Writing New Parameterized Matchers Quickly

MATCHER_P(name, param_name, description_string) { statements; }
MATCHER_Pk(name, param_1, ..., param_k, description_string) { statements; }

3.Writing New Monomorphic Matchers

T 类型的匹配器实现了匹配器接口,并为 T 类型执行两件事:它测试一个类型为 T 的值是否匹配匹配器,并且可以描述它匹配的类型。

4.Writing New Polymorphic Matchers

5.Legacy Matcher Implementation

用已有的API实现

6.Writing New Cardinalities

二、写代码

  1.AssignDataDefinitionValue函数

AnalyzerConfigCommon *ptr_analyzer_config;
  bison::Message<analyzer_proto::DevConfig> analyzer_dev_config;
  ptr_analyzer_config->AssignDataDefinitionValue(
      analyzer_dev_config.data().mutable_id(), id);

2.循环写法

TEST_F(AnalyzerDeviceChangeRequestTranslatorTest, TranslateEvent) {

  std::map<std::string, std::string> DEVICE_CHANGE_REQUEST_EVENT = {

      {DevOperations::ADD_DEVICE_OPERATION, AnalyzerEvents::EVENT_ADD_DEVICE},

      {DevOperations::UPDATE_DEVICE_OPERATION, AnalyzerEvents::EVENT_UPDATE_DEVICE},

      {DevOperations::REMOVE_DEVICE_OPERATION, AnalyzerEvents::EVENT_REMOVE_DEVICE},

};



  for (auto it : DEVICE_CHANGE_REQUEST_EVENT) {

    std::string dev_operation = it.first;;

    ConfigChangeRequest ccr;

    std::string event;



    AnalyzerConfigCommon *ptr_analyzer_config;

    bison::Message<analyzer_proto::DevConfig> analyzer_dev_config;

    ptr_analyzer_config->AssignDataDefinitionValue(

        analyzer_dev_config.data().mutable_dev_operation(), dev_operation);



    device_change_request_translator =

        std::make_unique<DeviceChangeRequestTranslator>(analyzer_dev_config);

    EXPECT_TRUE(device_change_request_translator->Translate(ccr, event));



    EXPECT_STREQ(it.first.c_str(), ccr[AnalyzerConfigChangeParam::DEV_OPERATION].c_str());

    EXPECT_STREQ(it.second.c_str(), event.c_str());

  }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_52541394

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值