1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef OHOS_MOCK_UTIL_H 17 #define OHOS_MOCK_UTIL_H 18 19 #include <any> 20 #include <map> 21 #include <string> 22 #include <type_traits> 23 #include <vector> 24 #include "hilog_tag_wrapper.h" 25 26 // inner utils class, you should not use this. 27 class ResultWrap { 28 public: ResultWrap(std::any result)29 ResultWrap(std::any result) 30 { 31 result_ = result; 32 } 33 ResultWrap()34 ResultWrap() {} 35 36 template <typename T> Get()37 T Get() const 38 { 39 return std::any_cast<T>(result_); 40 } 41 private: 42 std::any result_; 43 }; 44 45 // donnot use or change this map. 46 inline thread_local std::map<std::string, std::vector<ResultWrap>> g_mockMap; 47 inline thread_local std::map<std::string, std::vector<std::vector<ResultWrap>>> g_RefMap; 48 49 /** 50 * @brief Mock a member function. 51 * This macro function while create a definition of a function that expected to be mocked. 52 * @param ret Indicate the type of return value. 53 * Warning: this param only support basic type e.g int/string, if you need mock a function with sptr, use 54 * OH_MOCK_METHOD_RET_SPTR instead. 55 * @param className Indicate the className of function. 56 * @param funcName Indicate the functionName of function. 57 * @param ... Indicate the params of function. 58 */ 59 #define OH_MOCK_METHOD(ret, className, funcName, ...) \ 60 ret funcName(__VA_ARGS__) \ 61 { \ 62 std::string key = #className"_"#funcName"_"#__VA_ARGS__; \ 63 if (g_mockMap.find(key) == g_mockMap.end()) { \ 64 std::vector<ResultWrap> expectRets; \ 65 g_mockMap[key] = expectRets; \ 66 } \ 67 ret temp; \ 68 ResultWrap tempRet(temp); \ 69 auto it = g_mockMap.find(key); \ 70 if (it != g_mockMap.end()) { \ 71 std::vector<ResultWrap> expectRets = it->second; \ 72 if (!expectRets.empty()) { \ 73 tempRet = expectRets[0]; \ 74 expectRets.erase(expectRets.begin()); \ 75 } \ 76 g_mockMap[key] = expectRets; \ 77 } \ 78 return tempRet.Get<ret>(); \ 79 } 80 81 /** 82 * @brief Mock a member function with output params. 83 * This macro function while create a definition of a function that expected to be mocked. 84 * The output params must be the last params. 85 * @param ret Indicate the type of return value. 86 * Warning: this param only support basic type e.g int/string, if you need mock a function with sptr, use 87 * OH_MOCK_METHOD_RET_SPTR instead. 88 * @param className Indicate the className of function. 89 * @param funcName Indicate the functionName of function. 90 * @param ... Indicate the params of function. 91 */ 92 #define OH_MOCK_METHOD_WITH_OUTPUT_1(ret, oPName, className, funcName, ...) \ 93 ret funcName(__VA_ARGS__) \ 94 { \ 95 std::string key = #className"_"#funcName"_"#__VA_ARGS__; \ 96 if (g_mockMap.find(key) == g_mockMap.end()) { \ 97 std::vector<ResultWrap> expectRets; \ 98 g_mockMap[key] = expectRets; \ 99 } \ 100 ret temp; \ 101 ResultWrap tempRet(temp); \ 102 auto it = g_mockMap.find(key); \ 103 if (it != g_mockMap.end()) { \ 104 std::vector<ResultWrap> expectRets = it->second; \ 105 if (!expectRets.empty()) { \ 106 tempRet = expectRets[0]; \ 107 expectRets.erase(expectRets.begin()); \ 108 } \ 109 g_mockMap[key] = expectRets; \ 110 } \ 111 if (g_RefMap.find(key) == g_RefMap.end()) { \ 112 std::vector<std::vector<ResultWrap>> expectRefs; \ 113 g_RefMap[key] = expectRefs; \ 114 } \ 115 std::remove_reference_t<decltype(oPName)> tempOp; \ 116 ResultWrap tempRef(tempOp); \ 117 auto it1 = g_RefMap.find(key); \ 118 if (it1 != g_RefMap.end()) { \ 119 std::vector<std::vector<ResultWrap>> expectRefs = it1->second; \ 120 if (!expectRefs.empty()) { \ 121 tempRef = expectRefs[0][0]; \ 122 expectRefs.erase(expectRefs.begin()); \ 123 } \ 124 g_RefMap[key] = expectRefs; \ 125 } \ 126 oPName = tempRef.Get<decltype(tempOp)>(); \ 127 return tempRet.Get<ret>(); \ 128 } 129 130 /** 131 * @brief Mock a member function with return sptr<xxx> type value. 132 * This macro function while create a definition of a function that expected to be mocked. 133 * @param ret Indicate the type of return value. 134 * Warning: ret must be sptr<xxx> 135 * @param className Indicate the className of function. 136 * @param funcName Indicate the functionName of function. 137 * @param ... Indicate the params of function. 138 */ 139 #define OH_MOCK_METHOD_RET_SPTR(ret, className, funcName, ...) \ 140 ret funcName(__VA_ARGS__) \ 141 { \ 142 std::string key = #className"_"#funcName"_"#__VA_ARGS__; \ 143 if (g_mockMap.find(key) == g_mockMap.end()) { \ 144 std::vector<ResultWrap> tempExpectRets; \ 145 g_mockMap[key] = tempExpectRets; \ 146 } \ 147 ret tmp = nullptr; \ 148 ResultWrap tempRet(tmp); \ 149 std::vector<ResultWrap>& expectRets = g_mockMap[key]; \ 150 if (!expectRets.empty()) { \ 151 tempRet = expectRets[0]; \ 152 expectRets.erase(expectRets.begin()); \ 153 } \ 154 return tempRet.Get<ret>(); \ 155 } 156 157 /** 158 * @brief Mock a virtual or static member function. 159 * This macro function while create a definition of a function that expected to be mocked. 160 * @param ret Indicate the type of return value. 161 * Warning: this param only support basic type e.g int/string, if you need mock a function with sptr, use 162 * OH_MOCK_METHOD_RET_SPTR instead. 163 * @param className Indicate the className of function. 164 * @param funcName Indicate the functionName of function. 165 * @param ... Indicate the params of function. 166 */ 167 #define OH_MOCK_METHOD_WITH_DECORATOR(decorator, ret, className, funcName, ...) \ 168 decorator ret funcName(__VA_ARGS__) \ 169 { \ 170 std::string key = #className"_"#funcName"_"#__VA_ARGS__; \ 171 if (g_mockMap.find(key) == g_mockMap.end()) { \ 172 std::vector<ResultWrap> expectRets; \ 173 g_mockMap[key] = expectRets; \ 174 } \ 175 ret temp; \ 176 ResultWrap tempRet(temp); \ 177 auto it = g_mockMap.find(key); \ 178 if (it != g_mockMap.end()) { \ 179 std::vector<ResultWrap> expectRets = it->second; \ 180 if (!expectRets.empty()) { \ 181 tempRet = expectRets[0]; \ 182 expectRets.erase(expectRets.begin()); \ 183 } \ 184 g_mockMap[key] = expectRets; \ 185 } \ 186 return tempRet.Get<ret>(); \ 187 } 188 189 /** 190 * @brief Mock a virtual or static member function. 191 * This macro function while create a definition of a function that expected to be mocked. 192 * @param ret Indicate the type of return value. 193 * Warning: this param only support basic type e.g int/string, if you need mock a function with sptr, use 194 * OH_MOCK_METHOD_RET_SPTR instead. 195 * @param className Indicate the className of function. 196 * @param funcName Indicate the functionName of function. 197 * @param ... Indicate the params of function. 198 */ 199 #define OH_MOCK_METHOD_WITH_PREFIX_AMD_SUFFIX(prefix, suffix, ret, className, funcName, ...) \ 200 prefix ret funcName(__VA_ARGS__) suffix \ 201 { \ 202 std::string key = #className"_"#funcName"_"#__VA_ARGS__; \ 203 if (g_mockMap.find(key) == g_mockMap.end()) { \ 204 std::vector<ResultWrap> expectRets; \ 205 g_mockMap[key] = expectRets; \ 206 } \ 207 ret temp; \ 208 ResultWrap tempRet(temp); \ 209 auto it = g_mockMap.find(key); \ 210 if (it != g_mockMap.end()) { \ 211 std::vector<ResultWrap> expectRets = it->second; \ 212 if (!expectRets.empty()) { \ 213 tempRet = expectRets[0]; \ 214 expectRets.erase(expectRets.begin()); \ 215 } \ 216 g_mockMap[key] = expectRets; \ 217 } \ 218 return tempRet.Get<ret>(); \ 219 } 220 221 /** 222 * @brief Mock a global function. 223 * This macro function while create a definition of a function that expected to be mocked. 224 * @param ret Indicate the type of return value. 225 * Warning: this param only support basic type e.g int/string. 226 * @param funcName Indicate the functionName of function. 227 * @param ... Indicate the params of function. 228 */ 229 #define OH_MOCK_GLOBAL_METHOD(ret, funcName, ...) \ 230 ret funcName(__VA_ARGS__) \ 231 { \ 232 std::string key = #funcName"_"#__VA_ARGS__; \ 233 if (g_mockMap.find(key) == g_mockMap.end()) { \ 234 std::vector<ResultWrap> tempExpectRets; \ 235 g_mockMap[key] = tempExpectRets; \ 236 } \ 237 ret temp; \ 238 ResultWrap tempRet(temp); \ 239 std::vector<ResultWrap>& expectRets = g_mockMap[key]; \ 240 if (!expectRets.empty()) { \ 241 tempRet = expectRets[0]; \ 242 expectRets.erase(expectRets.begin()); \ 243 } \ 244 return tempRet.Get<ret>(); \ 245 } 246 247 /** 248 * @brief Mock a global template function with return sptr<xxx> type value. 249 * This macro function while create a definition of a function that expected to be mocked. 250 * @param ret Indicate the type of return value. 251 * Warning: ret must be sptr<xxx> 252 * @param className Indicate the className of function. 253 * @param funcName Indicate the functionName of function. 254 * @param ... Indicate the params of function. 255 */ 256 #define OH_MOCK_GLOBAL_TEMPLATE_METHOD_RET_SPTR(funcName, ...) \ 257 template <typename INTERFACE> sptr<INTERFACE> funcName(__VA_ARGS__) \ 258 { \ 259 std::string key = #funcName"_"#__VA_ARGS__; \ 260 if (g_mockMap.find(key) == g_mockMap.end()) { \ 261 std::vector<ResultWrap> tempExpectRets; \ 262 g_mockMap[key] = tempExpectRets; \ 263 } \ 264 sptr<INTERFACE> tmp = nullptr; \ 265 ResultWrap tempRet(tmp); \ 266 std::vector<ResultWrap>& expectRets = g_mockMap[key]; \ 267 if (!expectRets.empty()) { \ 268 tempRet = expectRets[0]; \ 269 expectRets.erase(expectRets.begin()); \ 270 } \ 271 return tempRet.Get<sptr<INTERFACE>>(); \ 272 } 273 274 /** 275 * @brief Mock a serial of expect results for specified member function. 276 * @param expectRetVec Indicate expect results vector. 277 * @param className Indicate the className of function. 278 * @param funcName Indicate the functionName of function. 279 * @param ... Indicate the params of function. 280 */ 281 #define OH_EXPECT_RET(expectRetVec, className, funcName, ...) \ 282 do { \ 283 std::string key = #className"_"#funcName"_"#__VA_ARGS__; \ 284 std::vector<ResultWrap> v; \ 285 for (auto e : expectRetVec) { \ 286 if (std::is_same<decltype(e), vector<bool>::reference>::value == true) { \ 287 bool conE = bool(e); \ 288 ResultWrap r(conE); \ 289 v.emplace_back(r); \ 290 } else { \ 291 ResultWrap r(e); \ 292 v.emplace_back(r); \ 293 } \ 294 } \ 295 g_mockMap[key] = v; \ 296 } while (0) 297 298 /** 299 * @brief Mock a serial of expect results for specified member function. 300 * @param expectRetVec Indicate expect results vector. 301 * @param className Indicate the className of function. 302 * @param funcName Indicate the functionName of function. 303 * @param ... Indicate the params of function. 304 */ 305 #define OH_EXPECT_RET_AND_OUTPUT(expectRetVec, expectOutputVec, className, funcName, ...) \ 306 do { \ 307 std::string key = #className"_"#funcName"_"#__VA_ARGS__; \ 308 std::vector<ResultWrap> v; \ 309 for (auto e : expectRetVec) { \ 310 if (std::is_same<decltype(e), vector<bool>::reference>::value == true) { \ 311 bool conE = bool(e); \ 312 ResultWrap r(conE); \ 313 v.emplace_back(r); \ 314 } else { \ 315 ResultWrap r(e); \ 316 v.emplace_back(r); \ 317 } \ 318 } \ 319 g_mockMap[key] = v; \ 320 std::vector<std::vector<ResultWrap>> vRefs; \ 321 for (auto eOuters : expectOutputVec) { \ 322 std::vector<ResultWrap> vRef; \ 323 for (auto eOuter : eOuters) { \ 324 if (std::is_same<decltype(eOuter), vector<bool>::reference>::value == true) { \ 325 bool conE = bool(eOuter); \ 326 ResultWrap r(conE); \ 327 vRef.emplace_back(r); \ 328 } else { \ 329 ResultWrap r(eOuter); \ 330 vRef.emplace_back(r); \ 331 } \ 332 } \ 333 vRefs.emplace_back(vRef); \ 334 } \ 335 g_RefMap[key] = vRefs; \ 336 } while (0) 337 338 /** 339 * @brief Mock a serial of expect results for specified global function. 340 * @param expectRetVec Indicate expect results vector. 341 * @param funcName Indicate the functionName of function. 342 * @param ... Indicate the params of function. 343 */ 344 #define OH_GLOBAL_EXPECT_RET(expectRetVec, funcName, ...) \ 345 do { \ 346 std::string key = #funcName"_"#__VA_ARGS__; \ 347 std::vector<ResultWrap> v; \ 348 for (auto e : expectRetVec) { \ 349 ResultWrap r(e); \ 350 v.emplace_back(r); \ 351 } \ 352 g_mockMap[key] = v; \ 353 } while (0) 354 355 #endif // OHOS_MOCK_UTIL_H