I have a little micro-framework called fff.h for generating fake functions (mocks) in C. I have blogged about it in the past, and there have been some exciting changes over the last few weeks that I’d like to share.
Background
The basic premise is that testing a C source file is difficult in idiomatic C because of all the external function calls that are hardwired into the production code. The way fff.h helps is to make it a one-liner to create fake implementations of these for the purposes of testing.
Now, the basic formula on my last project for testing a C module is like this:
This was crude but effective. What really grated with me though was the amount of repetitive code that had to be written to answer very basic questions. Was my fake function called? How many times? What parameters were passed in on each occasion? Was the unlock function called before the write function? To answer these questions we ended up writing endless amount of (not very pretty) code like this:
It seemed to me that it should be possible to write a macro to generate this code. This would tidy up the test files in terms of readability and would make it easier for my team to make tests. And that was the genesis of the Fake Function Framework.
The best introduction to the Fake Function Framework is on the fff github site so I won’t rehash that here.
New Developments
I have since moved on to a new project and haven’t thought about fff.h in a wee while. Through a variety of coincidences it happened that Tore, the architect on my previous project, met James Grenning during a training course and introduced him to fff.h. James played around with fff.h and sent me some great suggestions for cleanup, and how to improve fff.h to produce globally linkable fakes. At first I thought that this was an unneeded complication for an otherwise simple framework, but James convinced me that reusable fakes had a lot of value.
I set to work on making the generator able to generate the new style fakes. I don’t know I would have attempted this without having a full regression test suite for the framework.
The way it works is instead of using the usual syntax to create a fake using the FAKE_xxx_FUNCn macros, you create a header file to hold the declarations:
And then create an implementation file for the function definitions:
Then you can link many test suites against this single object without any problems. Simple!
Breaking Changes
There have been some breaking changes to fff.h to enable these new features, and I have also taken that opportunity to clean up some weaknesses in the previous design. But since fff.h is just a header file, both will happily exist in your codebase. All you have to do is name the new version of fff.h fff2.h and start using fff2.h in your new tests.
So theses are the basic changes you should know about if you are already familiar with the fake function framework. Somewhere in the test executable you must define the globals for fff. Why not put it beside the main function?
In the old version of fff.h there was a shortcut for resetting all the fakes in one step. This is now gone. The reason is that it only worked in C++ using static initializers and the introduction of global fakes were incompatible with this.
There has also been some cleanup. All the fake function framework variables have been moved into a struct to avoid polluting the global namespace.
And the variables for individual fakes are now defined in a struct.
Acknowledgements
The fake function framework would not exist as it does today without the support of key folks. Tore Martin Hagen (and his whiteboard), my partner-in-crime in Oslo, was instrumental during the genesis of fff. Jon Jagger, who during ACCU 2011 helped me teach the preprocessor to count. And James Grenning, who convinced me the value of global fakes, sent me a prototype Implementation, and showed me how expressive a DSL can be. Thanks to you all!
Request for comments
I hope you like the new changes, and if you have any feedback or suggestions for further improvements don’t hesitate to leave a comment or contact me via twitter.
Hi Mike,
I’ve started using FFF in a project and am very pleased with the results. The biggest pain point at the moment is the documentation- getting from what is documented in the github site vs whats actually implement in fff3. I’ve figured it all out, but it took awhile to get going with the framework. Overall I really like what your are doing- keep going… (and keep it simple…) (Also, BTW: I never use C++, so I view keeping FFF limited to just C as a good, value added, feature.)
Hi John, thanks for the feedback, really appreciated! I completely agree about the documentation, I haven’t updated it yet because I wanted to get some feedback first, but I realize now that was backwards thinking. I’ll get on it this weekend. Let me know if you have any more suggestions for improvements.
Hello Mike,
Attended BITsCon w. James Grenning as speaker and your framework was mentioned. Have since used it and found it very useful! One note though – when using custom fakes returning a value, it’s the FFF fake return value thats being returned. A more logical choice would be to use the return value from the custom fake, giving more control to which values are actually returned? Also, will you be doing a mock like API sometime in the future?
Hi,
Great that you find it useful, thanks for posting the comment.
You are absolutely correct about the custom fakes – they should return the value from the custom fake so this is a bug. I am on vacation at the moment but will post a fix next week.
I had originally planned some kind of mock-like interface since I found it so useful in c++ but I haven’t spent any time on it so far. If you have any suggestions for a syntax please drop me a line (or even better a pull request).
Thanks again for the feedback!
The latest fff now supports returning the value from the custom fake when it is a non-void function. Let me know if there are any issues.
Cheers,
Mike
Hello,
I used fff in a C+ (C++ without STL) project. Work pretty well.
But today I’m in front of a problem/limitation.
I would like to fake a template function. Is it possible ? How to do it ?
Other problem I discovered, don’t find a way to fake a static function inside a class.
Don’t find a way from the documentation or reading fff.h
Can be very usefull to do that.
Maybe you can just give me pointer on how to do implement it
Sincerely
Bertrand
Hi Bertrand,
Sorry, I don’t have any solution for that. fff is a framework for testing C code, so it doesn’t support templates or class functions.
For this type of problem I use the googlemock framework – it is very good at mocking C++ classes.
Regards,
Mik
I use GMock and HippoMock. They manage to mock classes easily. But static function inside class or template function I never manage to do that.
Will dive into these frameworks details
Thanks for your answer
Hi Mike, does FFF support faking variable arg funcs, e.g. “void func(int myInt, …)”. If so, whats the notation?
Sorry, fff doesn’t support variable length arguments on functions because it doesn’t know how many capture variables etc. to generate. Is it possible for you to create a fixed length function that delegates to the variable arg length function? Then you could create a fake for the delegation function.
Hope that helps.
Does it need to know? Isn’t this a simple case for variadic macros (http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html). If the number of args is vital, then perhaps something along the lines of http://stackoverflow.com/questions/1872220/is-it-possible-to-iterate-over-arguments-in-variadic-macros
A suggestion could be to just pass on the var args and not allow expectations on them
Actually, that is how the framework figures out how many arguments there are. For instance, when you define:
FAKE_VOID_FUNC(foo, int, double)
Internally that expands to:
FAKE_VOID_FUNC2(…)
The trouble is that the fake capture variables are defined at compile time whereas variadic functions don’t know the number of arguments until runtime.
Aah ok, I get it. Ok then, in my case I’ll just supply a “manual” stub over the variadic function. Thx for the answer.
No worries. I have added a todo to add a new macro FAKE_VARIADIC_FUNC that can fake a variadic function (but not capture the variables) just like you suggested. Thanks for the idea!
The one problem I found with the FAKE_*_FUNC() variants is that MSVS complains that you aren’t using all of the parameters (at least at the higher warning level I’m using). I had to resort to using the FAKE_*_FUNCn() internal variants directly, but it works like a charm.
HI can anyone tell how to mock the already defined function
Thank you so much for FFF! It’s by far the simplest solution I’ve found for mock functions that doesn’t require the overhead of other frameworks like what CppUMock and cmocka provide. The problem with those is that you have to set up expectations for your mocks even when you don’t care about what the mocks do. Allowing the test suite to do the checks as needed makes it much simpler.
I easily got up and running with it, in conjunction with the equally-simple Catch framework for unit testing.
Thanks! Glad it helped :-)
Hi Mik,
I am new for fff. I want to execute my own logic inside fake function that returns void. Can I use custom_fake for void return function?
Thanks
Exactly, look here for more info:
https://github.com/meekrosoft/fff#custom-return-value-delegate
Thanks Mike
Hello,
just wondering, can FFF call the original function ?
Yes, it can. You need to create a custom fake and forward in that.
https://github.com/meekrosoft/fff#custom-return-value-delegate
Thank you for the reply, I haven’t tried this, but it don’t understand:
#define MEANING_OF_LIFE 42
long my_custom_value_fake(void)
{
return longfunc0(); /* [1] Call original function */
}
TEST_F(
FFTestSuite,when_value_custom_fake_called_THEN_it_returns_custom_return_value)
{
longfunc0_fake.custom_fake = my_custom_value_fake;
long retval = longfunc0(); /* [2] */
ASSERT_EQ(MEANING_OF_LIFE, retval);
}
***************
There is no difference between the two calls at [1], and [2], so
I assume that the call at [1] will call the mock function, resulting in
infinite recursion.
Hi Evam,
Maybe I don’t understand what you are looking for. My assumption was that you wanted to create a fake for a function that also calls the function you are faking? It looks like you have this from your code example.
Then the second point is what are you testing? In your test code you are calling the original function you are faking. This looks suspicious to me. Normally you use fff to fake out functions when you do not want to call the original. E.g., say you have a function that calls a dangerous function:
int doLockWithCount()
{
static int lockCount;
if(lockComputer()) // dangerous function
{
locks++;
}
return lockCount;
}
And you want to write a test that makes sure the counting works – without actually locking the computer. What do you do? Well you have many options, but this is where you would create a fake if you use fff.
FAKE_VOID_FUNC(lockComputer);
So the call tree looks like testcode -> Function Under Test -> Fake
Maybe you can put up some code in a gist to show me what you are trying to do?
Hi,
I am just trying to understand the limitations for fff, I think you have
answered my question in that this is not possible. The use case
would be to enable/disable the fake functions on the fly.
FAKE_VOID_FUNC(lockComputer);
foo()
{
ENABLE_FAKE(lockComputer)
… replace calls to lockComputer …
DISABLE_FAKE(lockComputer)
… call original lockComputer …
}
I think to do something like this would require dlopen/dlsym(RTLD_NEXT)
on a posix system. And something like the MinHook library on a
windows system.
Thank you
Hi Mike, I have two functions a() and b() defined in the same source file, and a() calls b(). I create another source file for my gtest. In the test file I fake b() and then call a() in one of the tests. But this arrangement gives a link error because of multiple definitions for b(). Am I missing something or just being dense?
Not dense, just confusing the linker :-) There are a few approaches to this: You could split a() and b() into separate translation units and only link in the one you want in test. Or you could use a preprocessor directive or function pointer to swap the dependencies. You can find out more on this post on test seams: https://meekrosoft.wordpress.com/2012/07/20/test-seams-in-c-function-pointers-vs-preprocessor-hash-defines-vs-link-time-substitution/
Hello,
is it possible you could still add the FAKE_VARIADIC_FUNC macro?
It was literaly the first thing I tried to make a fake function for and found out it is unfortunately not supported yet. I saw the last comment about FAKE_VARIADIC_FUNC was in 2012. Maybe there isn’t enough demand? :)
Kind regards!
Took a shot myself and added the variadic function to fff: https://github.com/ivankoster/fff/commit/50bd6f47439f6f250a9f074740d58701261722fb
Hi Ivan,
This is cool! If you added a test case and a short documentation entry in README I’d love to merge this in ;-)
Cheers,
Mike
I’ve been using FFF for a while now, and am quite happy with it. The only problem I’ve run into, is when I need to use a faked function in two separate test files. If I re-fake the function in the second test file, I get a multiple definitions error. I guess I have multiple compile units for my tests, but I would prefer avoiding that.
Is there any way to reuse a fake using FFF?
Found the solution in the tests files for fff in the git repo. There is an example of making global fakes, by separating the declaration and the definition. Put the declaration of a fake in a header file, and the definition in a .c file and you’re good.
Only downside is, that you have to specify the number of arguments:
DEFINE_FAKE_VOID_FUNC1(voidfunc1, int);
I would be nice if there was a top-level macro that handles this, so I could just call something like:
DEFINE_FAKE_VOID_FUNC(voidfunc2, int, int, int);
But this will work for now! Hope this can provide some help for other people having the same need as me.
Great you found it! It would not be a big job to add the auto counting of parameters – feel free to send a pull request!
Please see my comments on the CMock vs FFF blog regarding the use of pointer arguments with FFF.
http://www.electronvector.com/blog/cmock-vs-fff-a-comparison-of-c-mocking-frameworks
Wow Ross, great write up! Thanks for taking the time to look into fff!
I’ve been using FFF and really love it. I have managed to embed this thing into out micro’s for testing. I had 1 problem which took a while to understand.
The return_val_seq is currently defined as a pointer. This works fine using gcc on a desktop, but on a micro, this address seems to be a bit loose and kept getting lost on the stack. I fixed it by setting this a fixed array and using memcpy() in the SET_RETURN_SEQ() function. Just a thing to keep in mind for anyone using this for embedded projects.
Otherwise, freaking awesome :)
Keep it up!
Pressed enter by mistake….with no correction of what i wrote, see below for a readable comment ;):
I’ve been using FFF and really love it. I have managed to embed this thing into our micros for testing. I had 1 problem which took a while to understand.
The “return_val_seq” is currently defined as a pointer.
This works fine using gcc on a desktop, but on a micro, this address seems to be a bit loose and it kept getting lost on the stack.
I fixed it by setting this as a fixed array and using memcpy() in the SET_RETURN_SEQ() function.
Just a thing to keep in mind for anyone using this for embedded projects.
Otherwise, freaking awesome :)
Keep it up!
Thanks Joel, glad it helps!
FAKE_VALUE_FUNC is causing a multiply defined symbol. The function I am trying to fake is in a library, so it should not be linked into the executable if the symbol is already defined (that’s just my opinion, though).
What am I doing wrong?
Still useful since this day. Love it!
Ps question: How to set a arg1_val when its a void*?
Like I want to set the void* out parameter of t he System IO call read(int, void *, size_t) – arg1.
I tried the following already without luck:
I tried also a memcpy:
I do know its possible with Google Test (using SetArgPointee)…
I really hope we could have an alternative instead of using a custom_fake..
With g++ compiler:
Can this be made easier?
My first comment is – better colors would be nice, black on grey is hard on my 58 year old eyes. Same problem at the accu.org site which has the fff content. Secondly, a better problem statement would be nice. What problem are we solving, the lack of real hardware in embedded systems and hence the need to write fake functions? What exactly do these functions do? Are these purely for book keeping? They give you a way to keep count of how many times they have been called or at a minimum if a function has been called at all?
The people at the company I work at are evangelizing this method but they are going about it like morons because they are
explaining why and how to use this FFF. Would be
nice if you can do a write up that average programmers
can understand.
Correction – I meant to say, “The people at the company I work at are evangelizing this method but they are going about it like morons because they are NOT explaining why and how to use this FFF”