如何编写单元测试调用Calculate函数及构建含2和0.8的VARIANT*参数
如何构建VARIANT*数组参数并编写Calculate函数的单元测试
我来帮你一步步搞定这两个问题——先解决怎么构建符合要求的VARIANT*参数,再给你写单元测试的示例,咱们慢慢来:
一、构建包含2和0.8的VARIANT*参数
因为Calculate要求的是指向VARIANT数组的指针(类型是VT_ARRAY | VT_VARIANT),所以核心是先创建COM的安全数组(SAFEARRAY),再把它包装到VARIANT里,最后取这个VARIANT的地址就行。以下是完整的代码实现:
// 1. 初始化要放入数组的两个元素 VARIANT intVar, floatVar; VariantInit(&intVar); // 必须初始化每个VARIANT VariantInit(&floatVar); // 设置第一个元素为整数2(类型VT_I4) V_VT(&intVar) = VT_I4; V_I4(&intVar) = 2; // 设置第二个元素为浮点数0.8(类型VT_R8) V_VT(&floatVar) = VT_R8; V_R8(&floatVar) = 0.8; // 2. 创建SAFEARRAY的边界描述:一维数组,共2个元素,下界从0开始 SAFEARRAYBOUND saBound; saBound.cElements = 2; saBound.lLbound = 0; // 创建存储VARIANT类型的SAFEARRAY SAFEARRAY* pSafeArray = SafeArrayCreate(VT_VARIANT, 1, &saBound); if (!pSafeArray) { // 处理创建失败的情况,记得先清理已初始化的VARIANT VariantClear(&intVar); VariantClear(&floatVar); return E_OUTOFMEMORY; } // 3. 将两个元素写入SAFEARRAY long indices[1]; // 一维数组的索引 // 写入第一个元素(索引0) indices[0] = 0; HRESULT hr = SafeArrayPutElement(pSafeArray, indices, &intVar); if (FAILED(hr)) { SafeArrayDestroy(pSafeArray); VariantClear(&intVar); VariantClear(&floatVar); return hr; } // 写入第二个元素(索引1) indices[0] = 1; hr = SafeArrayPutElement(pSafeArray, indices, &floatVar); if (FAILED(hr)) { SafeArrayDestroy(pSafeArray); VariantClear(&intVar); VariantClear(&floatVar); return hr; } // 4. 把SAFEARRAY包装到VARIANT中,现在&arrayVar就是需要的VARIANT*参数 VARIANT arrayVar; VariantInit(&arrayVar); V_VT(&arrayVar) = VT_ARRAY | VT_VARIANT; // 标记为VARIANT数组 V_ARRAY(&arrayVar) = pSafeArray; // 用完之后一定要清理:VariantClear会自动销毁内部的SAFEARRAY,以及里面的VARIANT元素 // VariantClear(&arrayVar); // VariantClear(&intVar); // VariantClear(&floatVar);
二、编写Calculate函数的单元测试
假设我们用Google Test框架来写测试(你也可以用其他框架,甚至写一个简单的控制台测试程序,逻辑是一样的),示例代码如下:
#include <gtest/gtest.h> #include "MyCom.h" // 引入你的COM组件头文件 TEST(MyComCalculateTest, ValidVariantArrayInput) { // 1. 初始化COM环境 HRESULT hr = CoInitialize(nullptr); ASSERT_EQ(S_OK, hr) << "COM环境初始化失败"; // 2. 创建MyCom对象实例 IMyCom* pMyCom = nullptr; hr = CoCreateInstance(CLSID_MyCom, nullptr, CLSCTX_ALL, IID_IMyCom, (void**)&pMyCom); ASSERT_NE(nullptr, pMyCom) << "无法创建MyCom对象实例"; // 3. 构建VARIANT*参数(复用上面的代码) VARIANT intVar, floatVar; VariantInit(&intVar); VariantInit(&floatVar); V_VT(&intVar) = VT_I4; V_I4(&intVar) = 2; V_VT(&floatVar) = VT_R8; V_R8(&floatVar) = 0.8; SAFEARRAYBOUND saBound; saBound.cElements = 2; saBound.lLbound = 0; SAFEARRAY* pSafeArray = SafeArrayCreate(VT_VARIANT, 1, &saBound); ASSERT_NE(nullptr, pSafeArray) << "SAFEARRAY创建失败"; long indices[1]; indices[0] = 0; hr = SafeArrayPutElement(pSafeArray, indices, &intVar); ASSERT_EQ(S_OK, hr) << "写入第一个数组元素失败"; indices[0] = 1; hr = SafeArrayPutElement(pSafeArray, indices, &floatVar); ASSERT_EQ(S_OK, hr) << "写入第二个数组元素失败"; VARIANT arrayVar; VariantInit(&arrayVar); V_VT(&arrayVar) = VT_ARRAY | VT_VARIANT; V_ARRAY(&arrayVar) = pSafeArray; // 4. 调用Calculate函数并验证结果 hr = pMyCom->Calculate(&arrayVar); ASSERT_EQ(S_OK, hr) << "Calculate函数调用失败"; // (可选)如果Calculate有输出结果或者修改了内部状态,可以在这里添加验证逻辑 // 比如假设Calculate计算了数组元素的总和,你可以获取结果并验证是否等于2.8 // 5. 清理所有资源 VariantClear(&arrayVar); VariantClear(&intVar); VariantClear(&floatVar); pMyCom->Release(); // 释放COM对象引用 CoUninitialize(); // 卸载COM环境 }
几个关键注意点:
- 资源清理:所有初始化的
VARIANT都要用VariantClear清理,COM接口指针要调用Release()释放,SAFEARRAY会被VariantClear自动销毁,不用手动调用SafeArrayDestroy。 - COM环境:在调用任何COM函数之前必须初始化COM环境(
CoInitialize),用完后要卸载(CoUninitialize)。 - 参数检查:如果
Calculate函数内部没有做参数合法性检查,测试时要确保传入的VARIANT类型正确(VT_ARRAY | VT_VARIANT),避免访问非法内存。
内容的提问来源于stack exchange,提问作者JoeyWang
相关产品推荐
相关产品推荐

