当前位置: 首页 > java >正文

gtest、gmock的使用

GoogleTest

GoogleTest 是由 Google 开发的一个 C++ 单元测试框架,用于编写、组织和运行自动化测试代码。它支持断言(如 EXPECT_EQASSERT_TRUE 等)、测试夹具(test fixtures)、参数化测试等高级功能,能够帮助开发者在开发过程中快速发现和定位问题。GoogleTest 具有良好的跨平台性,广泛用于 C++ 项目的测试验证,是工业界最常用的 C++ 测试框架之一。

断言

断言是用于单元测试中 验证程序行为是否符合预期 的语法工具。断言会对比测试值和期望值,若不一致,测试会标记失败。

ASSERT_*:当断言失败时,产生致命错误,并终止当前函数;

EXPECT_*:当断言失败时,产生非致命错误,并且不会终止当前函数

基本断言

 二元断言

字符串断言

 浮点数断言

指针断言

 异常断言

 注意:这里的statement可以是一段代码,也可以是函数调用,只要能触发一个异常就可以

容器断言

致命错误断言

用于验证代码是否会引发特定的致命错误(通常是程序终止)。

EXPECT_DEATH(statement, regex)

用于测试在执行 statement 时是否会导致程序崩溃,并且崩溃信息是否符合正则表达式 regex 的要求。statement:要测试的代码或函数调用。如果这段代码引发了致命错误,测试会通过regex:用于匹配崩溃信息的正则表达式。这个正则表达式用于检查程序崩溃时输出的错误信息是否符合预期。

致命错误介绍:

①abort()函数用于立即终止程序的执行。

②std::terminate()函数用于终止程序的执行。#include <exception>。它会调用一个终止处理程序,如果没有设置自定义终止处理程序,默认行为是调用abort()。

 ③std::exit()用于正常或异常终止程序的执行。允许程序指定一个退出状态,并在程序终止前执行所有由atexit()注册的函数清理。

谓词断言

1.EXPECT_PREDn

EXPECT_PREDn(predicate, actual .......n);

predicate:用户定义的谓词函数,可以是一个接收一个或多个参数并返回布尔值的函数

actual:被测试的值或表达式

bool isEven(int x) {return  n % 2 == 0;
}
TEST(myTest, checkEven) {EXPECT_PRED1(isEven, 4);EXPECT_PRED1(isEven, 5);
}

2.EXPECT_PRED_FORMAT*

用于使用谓词函数进行条件检查,并允许自定义错误消息的格式化(message)。适用于需要详细错误信息的场景,可以再测试失败时,提供更详细的上下文。

bool AreEqual(int a, int b) {if (a != b) {::testing::Message msg;msg << “Expected” <<  a  <<  “equals” << b;return false;}return true;
}
TEST(myTest, checkEven) {EXPECT_PRED_FORMAT2(isEven, 4,4);EXPECT_PRED_FORMAT2(isEven, 1,5);
}

SUCCEED

标记当前测试用例成功并立即结束测试。无论之前的测试代码是否存在错误,都会标记为成功,并且SUCCEED后面的代码不会被执行

TEST(MyTestSuite, SucceedExample) {int x = 10;int y = 20;if (x + y == 30) {SUCCEED();  // 满足条件,标记成功,立即结束测试}// 下面这行代码不会被执行FAIL() << "This should not happen!";
}

FAIL

标记当前测试用例为失败并立即结束测试。可以用来在测试代码中发现不可接受的状态时报告测试失败。在FAIL()之后的代码不会被执行。可以FAIL() << “  ”;用于在测试失败后输出一段信息

ADD_FAILURE/ADD_FAILURE_AT

ADD_FAILURE:用于手动添加测试失败的报告,而不依赖于某个特定断言的失败。可以在代码中的任何一个位置来标记,当执行到ADD_FAILUR时,gtest会报告测试失败,但程序仍然会继续执行后续的代码。

ADD_FAILURE_AT:允许在指定的文件名和行号处报告失败。

ADD_FAILURE_AT(__FILE__,__LINE__);__FILE__,__LINE__是c++的宏,表示当前文件和当前行,也可以是其他文件其他行。


EXPECT_THAT(actual, matcher)

用于进行复杂的条件检查,特别是在使用匹配器时。

actual:被测试的值或表达式或对象

matcher:用于检查actual的匹配器。匹配器可以是多种类型,用于执行不同的比较。

int x = 0;
EXPECT_THAT(x, Eq(0));

函数

testing::invoke()

用于在模拟对象的方法或函数时指定具体的行为。它可以将模拟的方法调用委托给一个用户定义的函数或仿函数,从而实现自定义的行为。testing::Invoke() 不仅可以用于普通函数,还可以用于仿函数、lambda 表达式或类成员函数等。Invoke() 通常与 Google Mock(Google Test 的一部分)中的 EXPECT_CALL() 或 ON_CALL() 语句一起使用,允许模拟对象在被调用时执行自定义逻辑,而不是返回默认值或固定的结果。

示例:

假设我们有一个接口 Foo,其中包含一个虚拟函数 DoSomething(),我们可以使用 testing::Invoke() 来指定这个函数在被调用时应该执行的具体行为。

testing::setArgReferee()

用于模拟函数中修改通过引用传递的参数的值。它可以被用来设置一个引用参数(或指针参数)在函数调用后应该持有的值。当我们使用 Google Mock 来模拟一个带有引用参数的函数时,SetArgReferee() 允许我们在该函数调用时修改这些引用参数的值,从而模拟函数的副作用。

基本语法:testing::setargreferee<N>(value);

其中

·  N:参数的索引(从 0 开始),表示哪个参数是引用类型,需要被修改。

·  value:当函数被调用时,将该值赋给引用参数。

示例:

假设我们有一个接口 Foo,其中包含一个方法 GetValue(int& out_value),它通过引用参数返回一些值。我们可以使用 testing::SetArgReferee() 来模拟这个行为,并设置引用参数的值。

常用宏

TEST()

TEST()第一个参数是Test Case的名称,第二个参数(隶属第一个Test Case参数)Test的名称。

一个测试的完整名称包括Test Case的名称以及Test的名称,不同Test Case的Test名称可以相同。

根据Test Case对测试结果进行分组,相关的test应放在同一个Test Case中

注意:gtest中main函数可以不用自己写,gtest会提供默认的main函数

提供的main示例:
int main(int argc, char **argv) {// 初始化 Google Test 框架testing::InitGoogleTest(&argc, argv);// 运行所有测试用例,并返回结果return RUN_ALL_TESTS();
}

TEST_F()

当我们想让多个test使用同一套数据配置时,就需要用到Test Fixtures了。

创建Fixtures步骤:

(1)派生一个继承testing::Test的类,并将该类(testing::Test)中的一些内容声明为protected类型,以便在子类中进行访问。

(2)根据实际情况,编写默认的构造函数或setup()函数,来为每个test准备所需的数据。

注意:setup()函数用于在每个测试用例运行之前执行更复杂的初始化逻辑,如设置共享数据或配置环境。

(3)根据实际情况,编写默认的析构函数或TearDown()函数,来释放SetUp()中分配的资源

(4)根据实际情况,定义test共享的子程序。

注意:

TEST_F() 宏允许测试用例访问测试夹具类中的 protected 成员变量和方法,所以如果测试代码中使用了Test Fixtures,应该使用TEST_F代替TEST。

如果你的测试用例在当前的 test.cpp 文件中不需要使用任何继承自 ::testing::Test 的类中的 protected 成员,并且不依赖于测试夹具中的初始化和清理逻辑,那么你可以使用 TEST() 宏,而不必使用 TEST_F() 宏。

②TEST_F()的第一个参数必须是Test Fixture类的名字。

③对于TEST_F()定义的每个test,GoogleTest将会在运行时创建一个新的Test Fixture,并立即通过SetUp()对其进行初始化,然后运行test,之后通过调用TearDown()进行数据清理,最后删除Test Fixture。需要注意的是,同一个Test Case中不同的test具有不同的Test Fixture对象,并且GoogleTest每次创建新的Test Fixture前都会先删除之前的Test Fixture。多个test不会重用相同的Test Fixture,某个test对fixture进行的修改对其他test无影响。

TEST_P()

是gtest中用于参数化测试的宏。通过参数化测试,可以编写一次测试代码,然后不用的输入值多次运行这个测试。

使用步骤:

1.定义一个测试夹具,并使用::testing::TestWithParam<T>来指定参数类型:

class myTestFixture : public ::testing::TestWithParam<int> {};
TEST_P(myTestFixture, checkEven) {int n = GetParam();EXPECT_EQ(n % 2, 0);
}

2.使用INSTANTIATE_TEST_SUITE_P来提供参数组合

INSTANTIATE_TEST_P(EvenTests,MyTestFixture,::testing::Values(2,4,6)
);

注意:除了Values传参外,还有以下几种

①Range(a,b[,step]):传入从a到b- 1的连续参数(或满足步长的间断参数)

②combine(g1, g2 .....):允许将多个参数组合在一起,进行笛卡尔积的参数化测试。这种方式适用于需要多个参数组合的情况。

示例:

class myTestFixture : public ::testing::TestWithParam<std::tuple<int, char>> {};
TEST_p(myTestFixture, checkCombination) {int num = std::get<0>(GetParam());char ch = std::get<1>(GetParam());
}
INSTANTIATE_TEST_SUITE_P(comboTests,myTestFixture,::testing::combine(::testing::Values(1, 2),::testing::Values(‘a’, ‘b’)
)
);

传递的参数是:

RUN_ALL_TESTS()

调用RUN_ALL_TESTS()宏在所有test都成功时,返回0;否则返回1。

RUN_ALL_TESTS()会运行所有关联的test,这些test可以来自不同的test case,甚至不同的源文件

注意:

①main()函数必须要返回RUN_ALL_TESTS()宏的结果。同时,RUN_ALL_TESTS()只能运行一次,多次调用会与GoogleTest的一些功能(如thread-safe、death tests)发生冲突。

②main()函数中的::testing::InitGoogleTest()函数将会解析命令行中的GoogleTest参数

GoogleMock

Google Mock(简称 GMock)是 Google 提供的一个 C++ 模拟框架,通常与 GoogleTest 搭配使用。它用于在测试中创建模拟对象(mock objects),从而隔离被测试代码与其依赖,验证函数调用行为是否符合预期。GMock 支持精细的调用控制(如调用次数、参数匹配、调用顺序等),使得单元测试更加灵活可靠,是编写高质量 C++ 测试不可或缺的工具。

mock作用:mock对象可以用来模拟其他类的行为。即自己实现一个假的依赖类,对这个类的方法行为和返回结果进行自定义。

注意:mock类可以模拟类的protected和private方法。Mock类不是简单地继承原本的接口,然后自己把它提供的方法实现;Mock类其实就等于原本的接口。对protected和private方法的Mock和public基本类似,只不过在Mock类中需要将这些方法设置成public。

使用mock类的一般流程

1.引入googlemock名称空间:引入相关的googlemock宏和函数

2.建立模拟对象:创建 Mock 类来替代接口或虚函数

        class MockFoo: public FooInterface

        MockFoo mockFoo;

3.设置默认行为通过ON_CALL(可选):为mock设置默认返回值或行为

4.设置期望通过EXPECT_CALL:设置具体的调用期望和行为

5.验证行为:运行测试,根据期望验证模拟对象的调用是否符合预期。

函数

MOCK_METHOD()

模拟类中创建模拟方法,可以处理任意个参数,也可以是mock_method1代表模拟的是一个参数的函数。

注意:mock_method()必须放在mock类的public处声明

基本语法:

MOCK_METHOD(return_type, method_name, (arg_types...), (specifiers));
·  return_type:方法的返回类型。
·  method_name:方法的名称。
·  arg_types:一个括号内的参数类型列表,可以为空,表示无参数。
·  specifiers:可选的修饰符,比如 const、override、noexpect、calltype(calltype)、ref(qualifier)等。

其中ref(qualifier)是用给定的引用限定符标记方法,例如ref(&)或ref(&&)。如果重写具有引用限定符的方法则需要。

(&)限定符:指定成员函数只能通过左值对象调用

(&&)限定符:指定成员函数只能通过右值对象调用

左值对象调用指:对象.成员函数()

右值对象调用指:std::move(对象).成员函数()

示例:

         

EXPECT_CALL()

EXPECT_CALL(mock对象, 方法的名称(匹配器machers))

注意:

  1. expect_call必须在任何执行模拟对象的代码之前。
  2. expect_call返回的是一个::tesing::Expecation类型的对象。Expecation表示某个期望调用的类
  3. ExpectationSet:用于对一组期望(Expectation)进行管理和验证

EXPECT_CALL()可调用(.连接)的方法

.with(multi_argument_matcher)

用于指定多个参数的自定义匹配规则。它可以为expect_call中函数的参数灵活的定义复杂的参数匹配条件

补充:常见比较器

①Args匹配器:将参数提取为多个部分,并在每个部分上应用匹配器
.With(Args<0,1>(ElementsAre(Le(5), Ge(3))));
表示第一个参数小于等于5,第二个参数大于等于3
②Allof匹配器:用于指定多个条件,所有条件都需要满足
.with(Allof( Args<0>(Gt(10)) ,  Args<1>( lt(20) ) ))
③Field匹配器:允许针对结构体或者类的某个字段进行匹配
struct mystruct {int x;int y;
}
.with(Field(&mystruct::x,Eq(5))));
④Trulu匹配器:可以自定义布尔函数来匹配参数
bool custommatcher(int arg1, int arg2) {return arg1  > arg2;
}
.with(Truly(custommatcher));

.timer(cardinality)

用于指定mock方法期望调用几次

cardinality:

①AnyNumber()表示这个方法可以被调用任意次数

②Between(m,n)表示函数被调用的次数在m和n之间,包含边界

③Atmost(n)、Atleast(n)表示至少之多被调用n次

④Exactly(n) /n表示精确调用次数n

注意:

1.如果没写timers,mock'也会自己推断次数

如果既没有指定willonce也没有指定willrepeatedly,则推断为Timers(1)

如果有n个(n >= 1)willonce子句,而没有willrepeat子句,则推断为Timers(n)

如果有n个(n >= 0)willonce子句,和一个willrepeat子句,则推断为Timers(Atleast(n))

2.timer子句最多只能使用一次

.insequence(sequence....)

用于指定函数调用按照一定顺序进行

序列sequences:默认时定义的期望行为是无序的。

示例:

何时调用getsize()和getvalue()是都可以的,无先后顺序。

EXPECT_CALL(mockFoo, getSize()).InSequence(s1, s2)代表将getsize()放在序列s1和s2中,并且在序列s1和s2中getsize()必须最先执行。而EXPECT_CALL(mockFoo, getValue()).InSequence(s1),把getvalue放在了序列s1中,但由于getsize()先放入的s1,因此在s1中geisize会比getvalue先执行,然后getvalue才执行。

运行结果:

注意:在将函数使用sequences限制后,调用这些函数的顺序必须遵照约定好的,否则会报错。

对于以上示例:可以不使用sequence,而是通过定义一个insequence对象insequence dummy;就能代表下面定义的所有EXPECT_CALL()函数都会按照他们定义的顺序进行执行。

 .after(expectations...)

指定模拟函数调用预计在一个或多个其他调用之后发生。参数最多是五个期望值或期望值对象。after子句可以在期望中使用任意次数

示例一:fun()的调用必须在init_x和init_y之后

using ::testing::expectation;
Expectation init_x = EXPECT_CALL(mockObj, Initx());
Expectation intt_y = EXPECT_CALL(mockObj, inity());
EXPECT_CALL(mockObj, fun()).After(init_x, init_y);

示例二:func()的调用必须在ExpectationSet中的所有Expectation执行完才可执行

using ::testing::ExpectationSet;
ExpectaionSet all_inits;
for (int i = 0; i < element_count(); i++ {all_inits  +=   EXPECT_CALL(mockObj, initElement(i));
}
EXPECT_CALL(mockObj, func()).After(all_inits);

.willonce()/.willrepeatedly()

是gmock中常用的行为定义函数,用于模拟函数在被调用时的返回行为或执行动作。主要用于EXCEPT_CALL中控制模拟对象的方法的行为。

willonce

用来指定模拟方法第一次调用时的行为。无论之后该方法被Timer(n)调用多少次,willonce之影响第一次调用。

使用场景:想让某个函数在第一次调用时返回一个值或执行一个动作,而后续的行为则可能不同。它只会影响函数的第一次调用。若函数被调用多次且没有定义后续的行为,gmock将抛出警告,提示多次调用但行为未定义。

注意:

①若没有Timers只使用一个willonce会推断为Timers(1)

②willeonce子句可以在期望中使用任意次数

③与willrepeatet不同,传递给每个willonce调用的操作最多只被调用一次

willRepeatedly

用来定义模拟方法被调用时的默认行为,即函数被多次调用时的重复行为。他会在每次调用时都执行指定的动作,除非有willonce先行覆盖了某些调用的行为。WillRepeatedly 通常用于函数的常规行为定义。如果你期望函数每次调用都返回相同的值或执行相同的动作,可以使用 WillRepeatedly。WillRepeatedly可以与 WillOnce 结合使用,来定义函数的某次调用和后续调用的不同行为。

.RetiresOnSaturation()

用于处理调用次数饱和的情况。当一个EXPEX_CALL()指定的调用次数已经达到上限时,RetiresOnSaturation()允许期望从匹配队列中移除,后续调用不再与该期望匹配,从而不再对后续调用施加影响。

示例:

.on_call(mockObj, methodName(Matchers.....))

用于设置mock方法的默认行为或返回值,特别是在没有明确的期望时,mock对象应该返回什么结果。

注意:

①如果同时使用ON_CALL和EXPECT_CALL,则EXPECT_CALL的行为会覆盖ON_CALL()的默认设置。

on_call可.的方法(子句)

(1).with(mulit_argument_matcher):当方法的参数符合某个条件时,执行某个默认行为/返回,

ON_CALL(mockObj, get).with(Lt(10).willByDefault(Return(42));

ON_CALL(mockObj, get).with(Rt(10).willByDefault(Return(42));

EXPECT_EQ(mock_obj.GetValue(5), 42); // 参数小于10,返回42

EXPECT_EQ(mock_obj.GetValue(15), 100);// 参数大于 10,返回100

注意:ON_CALL是宽松的,如果没有匹配.with()的参数,方法仍然可以被调用,或者继续使用其他默认行为。

(2).WillByDefault(action):用于设置mock方法默认行为的方法。如果ON_CALL本身定义了某个mock方法被调用时的条件(通过.will),则WillByDefault(action)用来指定的当这些条件满足时,该mock方法应执行的默认操作。

注意:

①这里的默认操作可以是返回具体的值,返回动态值,调用真实方法,触发其他行为等。

②每个ON_CALL语句只能使用WillByDefault语句一次。

gTest定义的处理mock的类

DefaultValue  ::testing::DefaultValue<T>

为某个类型设置全局的默认返回值

当mock对象的方法被调用时,如果没有明确的EXPECT_CALL()或ON_CALL()定义其返回行为,gmock会尝试返回DefaultValue类中为该类型设置的默认值。使得在没有明确期望的情况下,mock方法仍然可以返回一个有效值,从而避免因未定义行为导致的测试失败。

①DefaultValue<Type>::Set(value):为类型Type设置默认返回值

②DefaultValue<Type>::Clear():清除为类型Type设置的默认返回值,恢复到默认行为(数值类型默认为0,指针类型默认为nullptr,布尔默认为false,引用类型默认返回空对象)

示例:

TEST(...  ,  ...) {::testing::DefaultValue<int>::Set(42);myMock mock;EXPECT_CALL(mock, getnuber()).Times(1);EXPECT_EQ(mock.getnumber(), 42);::testing::DefaultValue<int>::clear();
}

NiceMock  ::testing::NiceMock<T>

提供了一个宽容的mock行为

作用1:

在使用NiceMock时,即使没有为某个方法设置明确的期望或默认返回值,调用这些方法时也不会导致测试失败或触发警告。(mock的默认行为:未明确期望(未使用EXPECT_CALL/ON_CALL)的mock调用会出发警告或导致测试失败)。

作用2:

NickMock会为未设置期望的函数提供默认返回值。对于数值类型返回0,对于指针返回nullptr,对于布尔返回false

作用3:

如果某个接口中有很多方法,而我们只关心其中几个,使用 NiceMock 可以避免为每个不关心的方法设置期望,同时还确保测试过程不会因未设置期望的方法调用而失败。

示例:

class MockInterface : public Interface {
public:MOCK_METHOD(int, getnumber, (), (override));MOCK_METHOD(int, dosomething, (), (override));
};
TEST(mockTest, niceMock) {NiceMock<MockInterface> mock_obj;EXPECT_CALL(mock_obj, getnumber).willonce(::testing::Return(42));EXPECT_EQ(mock_obj.getnumber(), 42);mock_obj.dosomething(); 即使dosomething没有设置期望,使用nicemock对象调用时    也不会报错或产生警告。
}

Naggymock:::testing::NaggyMock<T>

在没有明确设置期望的mock方法被调用时发出警告,但不会导致测试失败。

用于帮助开发者检测可能漏掉的期望设置,提醒开发者某个mock方法调用了却没有定义期望行为。但不会导致测试失败,会继续运行,调用没有期望的函数会返回默认值。

StrictMock:::testing::StrictMock<T>

具有严格行为要求的mock对象类型

要求每个mock方法的调用都必须明确设置期望。如果在测试过程中调用了未设置期望的mock方法,StrictMock会立即触发错误并导致测试失败。

Sequence/InSequence

用于控制mock调用顺序的工具。

(1)Sequence:确保mock对象的方法按照特定顺序调用。可以通过EXPECT_CALL为某些方法添加顺序约束,要求他们在特定顺序下执行。

示例:

class mockInterface : public Interface {
public:MOCK_METHOD(int, getnumber, (), (override));MOCK_METHOD(int, dosomething, (), (override));
};
TEST(mockTest, sequenceExample) {mockInterface mock_obj;Sequence s;EXPECT_CALL(mock_obj,  getnumber()).InSequence(s).willonce(Return(1));EXPECT_CALL(mock_obj, dosomething().InSequence(s);EXPECT_EQ(mock_obj.getnumber(), 1);mock_obj.dosomething();必须先调用getnumber再调用dosomething
}

(2)InSequence:确保在其生命周期内,所有EXPECT_CALL设置的期望必须按照顺序执行。与Sequence不同,它可以不显示创建Sequence对象,更加简介。

示例:

class mockInterface : public Interface {
public:MOCK_METHOD(int, getnumber, (), (override));MOCK_METHOD(int, dosomething, (), (override));
};
TEST(mockTest, sequenceExample) {mockInterface mock_obj;InSequence seq;EXPECT_CALL(mock_obj,  getnumber()).willonce(Return(1));EXPECT_CALL(mock_obj, dosomething();EXPECT_EQ(mock_obj.getnumber(), 1);mock_obj.dosomething();必须先调用getnumber再调用dosomething
}

Expectation/ExpectationSet

用于管理和组织mock方法调用期望的工具。允许定义和控制mock对象的行为,并确保特定的调用顺序或依赖关系

(1)Expectation

通过EXPECT_CALL可以创建一个Expectation对象 Expectation e = EXPECT_CALL(....)

e的作用:

将e传给After()可以指定某些期望,必须在其他期望之后才被调用

(2)ExpectationSet是一个集合容器,允许将多个Expectation对象组合在一起

当我们有多个期望,并且不需要按特定顺序执行时,可以使用ExpectationSet来管理这些期望。ExpectationSet es;  es += EXPECT_CALL();  es += EXPECT_CALL()

es的作用:

将es传给After()可以指定某个期望必须在某个集合中的期望都被调用之后才被调用。

Mather(匹配器)

用于定义/限制mock类中的方法的形参的值,如果method不需要形参可以保持match为空

通配符

1. _:匹配任意参数,不关心他的具体值或类型

EXPECT_CALL(mcokObj, method(_, _)).Times(1);

2. A<Type>()和An<Type>():匹配任意类型为Type的参数或对象,A<Type>()用于非引用类型,An<Type>()用于匹配引用类型。

复合匹配器

(1)AnyOf(.....)

如果参数符合其中任意一个条件,则匹配成功,用于参数有多种可能值时,用AngOf匹配多个可能的情况

EXPECT_CALL(mockObj, method(AnyOf(a, b, c....)).Times(1)

(2)AllOf(......)

当参数同时满足多个条件时,匹配成功。用来组合多个匹配器,要求所有匹配器都满足。

EXPECT_CALL(mockObj, method(AllOf(Gt(10), Lt(20))).Times(1)

(3)Not(matcher....)

反转匹配的结果,只有匹配器条件为假时,才会匹配成功

通用匹配器

浮点匹配器

字符串匹配器

mulit-argument matchers多参数匹配器

诸如Eq()、Ge().....等的

以及AllArgs(matcher)和Args<N1,N2, ........, NK>(matcher)

1.AllArgs(matcher)

用于将传递给模拟方法的所有参数作为整体,并将它们传递给另一个匹配器进行匹配。它适用于你想对多个参数一起应用匹配器时的场景。

2.Args<N1,N2, ........, NK>(matcher)

成员匹配器

(1)Filed(&class::field, m)

用于匹配类对象中特定字段的值

struct mystruct {int id;
};
mystruct obj = {5};
EXPECT_THAT(obj, &mystruct::id, 5);

(2)Filed(field_name,&class::field, m)

和第一个类似,但允许使用字段名称字符串表示

EXPECT_THAT(obj, Field(“id”, &mystruct::id, 5));

(3)Key(e)

用于匹配容器中指定键的存在,适用于map或类似数据结构,验证键是否存在。

std::map<std::string,int> mymap = {{“key1”, 1}};
EXPECT_THAT(mymap, Contains(key(“key1”)));

(4)Pain(m1, m2)

用于匹配键值对,常用于map中的元素

用于验证一个特定的键值对是否存在于容器中

EXPECT_THAT(mymap, Contains(Pair(“key1”, 1)));

(5)FieldsAre(m......)

用于同时验证多个字段的值

可传入多个Field、property匹配器,以检查对象的多个属性

EXPECT_THAT(mymap, FieldsAre(Field(&mystruct::id, 5),Field(&mystruct::name, “tests”))))

(6)Property(&class::property, m)

用于验证类中某个成员函数(通常是getter)返回的值。

其中property是某个成员函数的指针,m是期望的返回值

注意:property所代表的函数应该不带参数并且声明为const。

struct mystruct {int getValue() const {return 10;}
};
mystruct obj;
EXPECT_THAT(obj, Property(&mystruct::getvalue,10));

(7)Property(property_name,&class::property, m)

与上一个匹配器类似,允许通过属性名称来描述属性。

EXPECT_THAT(obj, Property(“value”,&mystruct::getvalue,10));

actions(行为)

Return

①ReturnArg<N>():用于在模拟对象的方法被调用时返回传入参数的第 N 个值。

②ReturnNew<T>(args...):用于模拟方法调用时返回一个新分配的对象指针。该对象的类型为 T,并且可以通过传递构造函数参数来初始化这个对象。

其中:

T:指定要创建的对象的类型。

args...:传递给对象构造函数的参数,可以是任意数量和类型的参数。

③ReturnPointee(ptr):用于模拟方法调用时返回指向某个对象的指针,具体来说,它返回指向 ptr 指向的值的指针。

④ReturnRef(variable):

功能:用于模拟方法调用时返回一个变量的引用。

用法:适用于需要返回引用类型的函数,可以直接返回一个现有变量的引用。

⑤ReturnRoundRobin({a1, ..., ak})

功能:用于模拟方法调用时按顺序返回给定列表中的值,返回值会循环使用。

用法:适合需要多次调用返回不同值的场景。

side effects

Invoke

①f:传给模拟函数的参数可调用对象,f可以是任何可调用的对象,如普通函数、lambda或functor

②Invoke(f):

③Invoke(object_pointer, &class::method)

④InvokeWithoutArgs(f)

调用不带参数的全局或静态函数f

⑤InvokeWithoutArgs(object_pointer, &class::method)

调用指定对象的无参数成员函数

Default Action

在设置期望时如果没有为特定的函数调用指定其他行为,调用DoDefault()可以确保模拟对象按照正常的、未被覆盖的方式执行。

        

Composite Actions

①DoAll(a1,a2,.......) :依次执行所有提供的子动作,a1到an,并在每次调用时返回最后一个动作的结果。前n-1个动做必须返回void,并且前n-1个动作可以读取传递给模拟的函数的参数,但不能修改他们。最后一个子动作可以读取或者修改传递给模拟函数的参数。

②IgnoreResult(a)

执行动作 a,但忽略其返回值。a 不能是一个返回 void 的函数。

.willonce(::testing::IgnoreResult(a))

③withArgs<N>(a)

将模拟函数的第N个参数传递给动作a并执行该动作。

④withArgs<N1,N2,......>(a)

将模拟函数的多个参数传递给动作a并执行该动作。

注意:其中x和y就是传递给somemethod的第一二个参数

⑤withoutArgs(a)

执行动作a,不做任何操作

基数(cardinalities)

用于timer()中来指定模拟函数将被调用多少次

http://www.xdnf.cn/news/1408.html

相关文章:

  • Google搜索技巧
  • 【官方正版,永久免费】Adobe Camera Raw 17.2 win/Mac版本 配合Adobe22-25系列软
  • 若依项目部署小结
  • OSPF的优化
  • 进程(Process)详解
  • 【自然语言处理与大模型】大模型参数规模与部署配置调查2025第一季度
  • LSA六种类型
  • VScode
  • 5.3 分布式事务
  • git lfs下载大文件限额
  • 查询Hologres或postgresql中的数据
  • php基础
  • 算法训练营第一天|704.二分查找、27.移除元素、977.有序数组的平方
  • 集结号海螺捕鱼组件搭建教程与源码结构详解(第四篇)
  • crictl 拉取镜像报错 Unimplemented desc = unknown service runtime.v1.ImageService
  • redis 使用 Docker 部署 简单的Redis 集群(包括哨兵机制)
  • 修电脑之电脑没有声音
  • 武装Burp Suite工具:xia SQL自动化测试_插件
  • date-picker组件的shortcuts为什么不能配置在vue的data的return中
  • 小红书文字配图平替工具
  • Vue3-原始值的响应式方案ref
  • 实时数仓体系概览与架构演进
  • python实战项目64:selenium采集软科中国大学排名数据
  • Django DRF实现用户数据权限控制
  • 服务器数据恢复—双循环RAID5数据恢复揭秘
  • 2025.04.23华为机考第二题-200分
  • 第七节:进阶特性高频题-Vue3的ref与reactive选择策略
  • 数据结构初阶:二叉树(四)
  • CSS3 基础(边框效果)
  • 从 Vue 到 React:React.memo + useCallback 组合技