Closed laurensmiers closed 5 years ago
I also struggled with those static inline functions, and haven't really found a good solution.
For now, i am doing
#if !defined(UNITTEST) /* for unit test, mocks will be generated */
static incline void foo(void) {
// act like foo
}
#endif
and the UNITTEST is added to the -D options of gcc only when building for unit test.
The drawback: we can't unit test this actual function, and even if we're testing the component where this function resides we use a mock function...
So, I'm also curious about other solutions?
@SteinHeselmans thanks for your suggestion. I was doing the same as you but then I bumped into static inline functions in third-party library stuff that I would like to leave untouched (so altering them is not an option...) . That's why I 'mocked' the headers containing these static inline functions but it also doesn't feel like a solid solution...
I have the same problem. I can fix it by creating a new header file with no inline functions, but it's a tedious process so I was wondering if there is a config option for this ? Maybe something like the opposite of ":strippables" where you can explicitly add functions to be mocked ?
Yeap, I will agree with my fellow raccoons, mocking static inline functions would be a nice feature. I am now working with nordic's NRF5 SDK which is full of those.
Hi, +1 from me as well, I feel this would be an awesome feature. I'm working with STM32 dev tool libraries which contain loads of static inliners - and I imagine a lot of SDKs will have these too. The only practical solution I found was to manually mock the header files which is a long tedious process.
Looking forward to having ceedling do this for me! 💯
+1 Yes, this would be a good feature
Hi, I've also encountered problem with static inline functions. It would be definitely something nice to have.
+1 from me as well, I'd also greatly appreciate some other ideas for a 'more automatic' solution.
Some initial thoughts, just to start the discussion:
Right now, ceedling/cmock is including the original to-mock header in his mock-header (this is the header with all the *_Expect, ... Not sure if this is the official name).
If we make mocks for the static-inline functions, we shouldn't include the original to-mock header anymore (otherwise we would have multiple definitions I guess). The mock header will contain all functions (inline and normal).
So basically, stripping "static inline" and the implementation of the static-inline functions from the original header before starting the parsing. This should make cmock handle the static-inline functions as a normal function I guess?
However, if we don't include the original header, we have to make sure no defines/macros/... are lost. So these would have to be copied to the mock-header as well.
+1 from me on this front. Biggest issue is with vendor code.
+1 literally every single SDK driver I use from NXP and Nordic have these. Many from TI do as well. Please please PLEASE let us mock these, I can't think of a good reason why you wouldn't?
+1 from me too. I'm having issues with it too! I tried creating a new header file and putting the function prototype in it, but then I get errors because of multiple declarations (because another file uses the same function)...
@alexiabrazeau there is already a solution merged into latest cmock - does that work for you?
@Letme Hi, my issue is that I am trying to mock a function that doesn't have a prototype. It's the first time I see this, the function is declared in the header file like so :
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}
I am really confused as to how I'll mock this function to be honest, it's a very specific case
I know this is old, but the method I'm using to mock static inline function is based on some trivia:
So what I usually do is copy the content of the original header file into the new one and mock everything in it (or not depending on the need) and then I include the unit tests mocking folder before the other ones (as the first entry for example) this way the mocked header is the one taken instead of the real one from the library. Works like a charm and it allows your original source files to be free of unit test conditional compilations (which means you don't need to modify library files)
Problem with it is that you usually have to copy the whole header file and mock some other stuff, when the library file changes, you have to update yours as well, nothing extraordinary but still some maintenance.
btw it's basically the same idea as when you wanna override the default malloc implementation for example, you just snatch the request of the dynamic library linking at runtime to redirect it, well it's the same idea here but with the header files search
Hi,
This is more a question than an issue, but maybe CMock has a solution for this that I don't know yet. I found this issue #103, but this only covers 'static' functions not 'static inline' as far as I can understand.
I was wondering what the best strategy is to mock "static inline" functions using CMock (or if there is a way to do this?).
Some context: I'm writing an application on a Kinetis Freescale board and using Ceedling/Cmock to write my tests/generate mocks. I am using it quite successfully but now I am trying to mock a driver from the Kinetis SDK. The problem was that CMock was not generating mocks because the functions were all of the following signature:
I tweaked CMock to have it make mocks for this kind of function as well but I forgot that the compiler/linker will now have 2 definitions in the mocked header file (since CMock includes the original header file in the mocked header file).... This gives the following linking error when trying to compile the mock:
I circumvented the issue for now by copying the SDK header file to a mocked SDK folder (and setting it as the first include path before the actual SDK when compiling the mocks/tests). I also removed the implementation of the static inline functions (and also removing the static inline to have them recognized by CMock as 'normal' functions). So f.e.
static inline void PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_pin_config_t *config) {...}
becomesvoid PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_pin_config_t *config);
in the new mock port.h header file That way I can have _Expect, _Ignore, etc. for these SDK functions (I just want mocks for it that I can use for the tests).I don't want to 'adapt'/touch the ksdk driver code to the tests, so I am wondering what's the best strategy to tackle this sort of functions? Does CMock provide something to do this or is the way described above the way to go or something else...?
Thanks for reading the wall of text if you got this far, KR,
Laurens