1 // Copyright 2021, Hubert Jagodziński
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 // Author: hubert.jagodzinski@gmail.com (Hubert Jagodziński)
29 // C Mock - Google Mock's extension allowing a function mocking.
31 // This file implements DECLARE_FUNCTION_MOCKn() and IMPLEMENT_FUNCTION_MOCKn()
32 // macros of various arities.
34 #ifndef CMOCK_INCLUDE_CMOCK_CMOCK_FUNCTION_MOCKERS_H_
35 #define CMOCK_INCLUDE_CMOCK_CMOCK_FUNCTION_MOCKERS_H_
42 #include "cmock/cmock-internal.h"
44 #define CMOCK_INTERNAL_DECLARE_FUNCTION_MOCKN(_ClassName, _FunctionName, _N, _Signature) \
47 typedef CMOCK_INTERNAL_RETURN_TYPE(_Signature) (*func_type)(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)); \
50 static func_type real; \
55 CMOCK_INTERNAL_RETURN_TYPE(_Signature) operator()(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)); \
56 ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> cmock_func(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)); \
59 static func_type lookup(); \
60 static CMOCK_INTERNAL_RETURN_TYPE(_Signature) call(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)); \
62 static _ClassName *instance; \
64 ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> mocker; \
66 friend CMOCK_INTERNAL_RETURN_TYPE(_Signature) _FunctionName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)); \
69 #define CMOCK_INTERNAL_IMPLEMENT_FUNCTION_MOCKN(_ClassName, _FunctionName, _N, _Signature) \
70 _ClassName::_ClassName() { \
74 _ClassName::~_ClassName() { \
78 CMOCK_INTERNAL_RETURN_TYPE(_Signature) _ClassName::operator()(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) { \
79 mocker.SetOwnerAndName(this, #_FunctionName); \
80 return mocker.Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \
83 ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> _ClassName::cmock_func(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) { \
84 mocker.RegisterOwner(this); \
85 return mocker.With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \
88 _ClassName::func_type _ClassName::lookup() { \
89 return (_ClassName::func_type)dlsym(RTLD_NEXT, #_FunctionName); \
92 CMOCK_INTERNAL_RETURN_TYPE(_Signature) _ClassName::call(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) { \
93 if (instance != NULL) { \
94 return (*instance)(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \
98 std::ostringstream msg; \
99 msg << "Error: Function " << #_FunctionName; \
100 msg << " not found. Neither mock nor real function is present."; \
101 throw std::logic_error(msg.str()); \
103 return real(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \
106 _ClassName *_ClassName::instance = NULL; \
107 _ClassName::func_type _ClassName::real = lookup(); \
109 CMOCK_INTERNAL_RETURN_TYPE(_Signature) _FunctionName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) { \
110 return _ClassName::call(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \
113 #define DECLARE_FUNCTION_MOCK0(c, n, ...) \
114 CMOCK_INTERNAL_DECLARE_FUNCTION_MOCKN(c, n, 0, (::testing::internal::identity_t<__VA_ARGS__>))
116 #define IMPLEMENT_FUNCTION_MOCK0(c, n, ...) \
117 CMOCK_INTERNAL_IMPLEMENT_FUNCTION_MOCKN(c, n, 0, (::testing::internal::identity_t<__VA_ARGS__>))
119 #define DECLARE_FUNCTION_MOCK1(c, n, ...) \
120 CMOCK_INTERNAL_DECLARE_FUNCTION_MOCKN(c, n, 1, (::testing::internal::identity_t<__VA_ARGS__>))
122 #define IMPLEMENT_FUNCTION_MOCK1(c, n, ...) \
123 CMOCK_INTERNAL_IMPLEMENT_FUNCTION_MOCKN(c, n, 1, (::testing::internal::identity_t<__VA_ARGS__>))
125 #define DECLARE_FUNCTION_MOCK2(c, n, ...) \
126 CMOCK_INTERNAL_DECLARE_FUNCTION_MOCKN(c, n, 2, (::testing::internal::identity_t<__VA_ARGS__>))
128 #define IMPLEMENT_FUNCTION_MOCK2(c, n, ...) \
129 CMOCK_INTERNAL_IMPLEMENT_FUNCTION_MOCKN(c, n, 2, (::testing::internal::identity_t<__VA_ARGS__>))
131 #define DECLARE_FUNCTION_MOCK3(c, n, ...) \
132 CMOCK_INTERNAL_DECLARE_FUNCTION_MOCKN(c, n, 3, (::testing::internal::identity_t<__VA_ARGS__>))
134 #define IMPLEMENT_FUNCTION_MOCK3(c, n, ...) \
135 CMOCK_INTERNAL_IMPLEMENT_FUNCTION_MOCKN(c, n, 3, (::testing::internal::identity_t<__VA_ARGS__>))
137 #define DECLARE_FUNCTION_MOCK4(c, n, ...) \
138 CMOCK_INTERNAL_DECLARE_FUNCTION_MOCKN(c, n, 4, (::testing::internal::identity_t<__VA_ARGS__>))
140 #define IMPLEMENT_FUNCTION_MOCK4(c, n, ...) \
141 CMOCK_INTERNAL_IMPLEMENT_FUNCTION_MOCKN(c, n, 4, (::testing::internal::identity_t<__VA_ARGS__>))
143 #define DECLARE_FUNCTION_MOCK5(c, n, ...) \
144 CMOCK_INTERNAL_DECLARE_FUNCTION_MOCKN(c, n, 5, (::testing::internal::identity_t<__VA_ARGS__>))
146 #define IMPLEMENT_FUNCTION_MOCK5(c, n, ...) \
147 CMOCK_INTERNAL_IMPLEMENT_FUNCTION_MOCKN(c, n, 5, (::testing::internal::identity_t<__VA_ARGS__>))
149 #define DECLARE_FUNCTION_MOCK6(c, n, ...) \
150 CMOCK_INTERNAL_DECLARE_FUNCTION_MOCKN(c, n, 6, (::testing::internal::identity_t<__VA_ARGS__>))
152 #define IMPLEMENT_FUNCTION_MOCK6(c, n, ...) \
153 CMOCK_INTERNAL_IMPLEMENT_FUNCTION_MOCKN(c, n, 6, (::testing::internal::identity_t<__VA_ARGS__>))
155 #define DECLARE_FUNCTION_MOCK7(c, n, ...) \
156 CMOCK_INTERNAL_DECLARE_FUNCTION_MOCKN(c, n, 7, (::testing::internal::identity_t<__VA_ARGS__>))
158 #define IMPLEMENT_FUNCTION_MOCK7(c, n, ...) \
159 CMOCK_INTERNAL_IMPLEMENT_FUNCTION_MOCKN(c, n, 7, (::testing::internal::identity_t<__VA_ARGS__>))
161 #define DECLARE_FUNCTION_MOCK8(c, n, ...) \
162 CMOCK_INTERNAL_DECLARE_FUNCTION_MOCKN(c, n, 8, (::testing::internal::identity_t<__VA_ARGS__>))
164 #define IMPLEMENT_FUNCTION_MOCK8(c, n, ...) \
165 CMOCK_INTERNAL_IMPLEMENT_FUNCTION_MOCKN(c, n, 8, (::testing::internal::identity_t<__VA_ARGS__>))
167 #define DECLARE_FUNCTION_MOCK9(c, n, ...) \
168 CMOCK_INTERNAL_DECLARE_FUNCTION_MOCKN(c, n, 9, (::testing::internal::identity_t<__VA_ARGS__>))
170 #define IMPLEMENT_FUNCTION_MOCK9(c, n, ...) \
171 CMOCK_INTERNAL_IMPLEMENT_FUNCTION_MOCKN(c, n, 9, (::testing::internal::identity_t<__VA_ARGS__>))
173 #define DECLARE_FUNCTION_MOCK10(c, n, ...) \
174 CMOCK_INTERNAL_DECLARE_FUNCTION_MOCKN(c, n, 10, (::testing::internal::identity_t<__VA_ARGS__>))
176 #define IMPLEMENT_FUNCTION_MOCK10(c, n, ...) \
177 CMOCK_INTERNAL_IMPLEMENT_FUNCTION_MOCKN(c, n, 10, (::testing::internal::identity_t<__VA_ARGS__>))
179 #endif // CMOCK_INCLUDE_CMOCK_CMOCK_FUNCTION_MOCKERS_H_