• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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