C++test 学习之桩函数

本文介绍了C++test中桩函数的三种类型:original、auto和user,详细解释了每种类型的含义及其优先级。此外,还展示了如何通过自定义桩函数实现100%的代码覆盖率,并提供了一个具体的malloc函数桩函数示例。

在C++test中,桩函数分为original, auto ,user三种类型。

original的桩函数时在原程序中定义的,auto是自动生成,user是用户自定义的。

Definition: The current definition/stub type:
• User: User provided definition/stub will be used.
• Safe: C++test's safe definition/stub will be used.
• Original: Original definition will be used.
• Auto: C++test's auto definition/stub will be used.
Note: When you first open the Stubs view, it will be empty. A message stating "Symbols data not collected" will be displayed.
• N/A (not required): Definition is not available, not needed by the linker.
• N/A: Definition is not available, but is needed by the linker (in most cases, this will result in a linker error when building the test executable).

如果是,在被测文件中调用的函数定义在头文件中,并且自定义了该函数的桩函数(user),则测试文件调用user桩函数。

所以,user>original>auto

 

自动生成的桩函数带有CppTest_Auto_Stub_前缀,用户自定义的桩函数是CppTest_Stub_

 

系统生成的安全桩函数,优先级大于原来的函数。安全桩函数是为了代替原来的一些危险函数而自定生成的。使用安全桩函数会在单元测试中避免一些问题。如果不想使用系统自动生成的桩函数,则在测试配置中,去掉安全桩函数的路径即可。

 

利用测试用例驱动的桩函数可以达到100%的覆盖率

例如,通常对malloc函数的覆盖率都是50%,这里利用桩函数来达到100%。

#include <string>
#include <stdlib.h>
EXTERN_C_LINKAGE void* CppTest_Stub_malloc(size_t size)
{
std::string testSuiteName = CppTest_GetCurrentTestSuiteName();
std::string testCaseName = CppTest_GetCurrentTestCaseName();
if ((testSuiteName == "AllocTestSuite") &&
(testCaseName.find("nomemory") != std::string::npos))
{
// Simulate no memory situation.
return 0;
}
return malloc(size);
}

<think> 我们正在讨论C++Test中的函数(stub)如何按条件返回1或0。 根据用户之前的上下文(关于函数重载、main函数和返回对象的函数),我们可以推断用户可能在单元测试中需要控制函数的行为。 C++Test是一个单元测试工具,函数用于替换被测代码依赖的外部函数,以便在测试中模拟不同的行为。 在C++Test中,函数可以通过以下方式按条件返回不同的值(如1或0): 1. 使用条件语句判断测试场景(如输入参数、全局状态等) 2. 返回预设的值序列(按调用顺序返回不同值) 3. 根据测试用例设置的条件返回 具体步骤(以C++Test为例): a) 创建函数:在测试用例中,为需要函数创建一个。 b) 设置函数行为:可以设置函数在特定条件下返回指定值。 示例:假设有一个函数`int external_func(int param)`,我们想在测试中模拟它,当参数大于0时返回1,否则返回0。 在C++Test中,可以通过以下方式实现: - 使用`CPPTEST_P_SET_STUB`宏来设置函数的行为(具体宏可能因版本而异,但原理类似)。 - 或者在测试用例中直接定义一个函数,并使用条件语句。 示例代码(概念性,非实际API): ```cpp // 假设我们有一个被测函数,它调用了一个外部函数external_func int function_under_test(int x) { if (external_func(x) > 0) { return 100; } else { return -100; } } // 在测试用例中,我们设置函数 TEST(TestSuite, TestCase) { // 设置函数:当参数大于0时返回1,否则返回0 STUB_SET(external_func) { if (param1 > 0) { // 假设param1是external_func的第一个参数 return 1; } else { return 0; } }; // 执行测试 ASSERT_EQ(function_under_test(10), 100); // 当输入10(大于0)时,external_func返回1,所以function_under_test返回100 ASSERT_EQ(function_under_test(-5), -100); // 当输入-5(不大于0)时,external_func返回0,所以function_under_test返回-100 } ``` 注意:上述代码中`STUB_SET`是示意宏,实际在C++Test中可能有不同的方式,例如使用`CPPTEST_SET_STUB_RETURN`或通过回调函数设置。 另一种方法是使用函数的序列返回值(如果条件是按调用次数): ```cpp STUB_SET_RETURN_VALUES(external_func, 1, 0); // 第一次调用返回1,第二次返回0 ``` 但用户的需求是“按条件”,所以第一种方式更合适。 如果用户使用的是较新版本的C++Test,可以参考其文档中关于“条件”或“智能”的部分。 总结:在C++Test中,函数按条件返回值可以通过在函数实现中加入条件判断来实现。具体设置方法取决于C++Test的API,但原理相同。 §§相关问题§§ 1. 如何在C++Test中设置函数返回多个不同的值(按调用顺序)? 2. C++Test函数和模拟函数(mock)有什么区别? 3. 如何在C++Test中模拟异常抛出? </think> 在C++Test中,可以通过以下方法实现函数按条件返回1或0: ### 函数条件返回的实现方法 1. **使用条件语句** 在函数内部添加条件判断逻辑: ```cpp // 函数示例 int StubFunction(int param) { if (/* 条件表达式 */) { // 例如:param > 0 return 1; } else { return 0; } } ``` 2. **通过全局变量/成员变量控制** 结合测试用例设置控制变量: ```cpp // 测试控制变量 static bool returnFlag = false; // 函数实现 int StubFunction() { return returnFlag ? 1 : 0; } // 测试用例中控制返回值 TEST_CASE("Test Case") { returnFlag = true; // 设置返回1 REQUIRE(functionUnderTest() == 1); returnFlag = false; // 设置返回0 REQUIRE(functionUnderTest() == 0); } ``` 3. **使用参数化函数** 通过传入参数决定返回值: ```cpp // 带参数的函数 int ConditionalStub(bool shouldReturnOne) { return shouldReturnOne ? 1 : 0; } // 测试用例调用示例 TEST_CASE("Parametrized Stub") { REQUIRE(ConditionalStub(true) == 1); REQUIRE(ConditionalStub(false) == 0); } ``` ### 关键注意事项 1. **明确函数替换目标** 确保函数签名与原始函数完全一致(包括返回类型和参数)[^1] 2. **隔离测试状态** 使用`SETUP/TEARDOWN`确保每次测试前重置控制变量: ```cpp TEST_SUITE_BEGIN("TestSuite"); SETUP() { returnFlag = false; } // 每次测试前重置 ``` 3. **结合C++Test管理API** 使用`CPPTEST_SET_STUB`宏动态替换函数: ```cpp CPPTEST_SET_STUB("OriginalFunction", (void*)StubFunction); ``` 4. **处理对象状态** 若涉及类成员函数,需正确处理对象生命周期[^3],例如: ```cpp class TestStub { public: int memberStub() { return (this->condition) ? 1 : 0; } }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值