Open frankbenoit opened 8 years ago
Hi Frank,
the custom_fake function pointer provided by FFF allows you to dynamically change the function used for your tests: Custom Return Value Delegate You can also use the custom_fake for void functions.
Is that what you are looking for or am I missing something?
Balthasar
Perhaps I am missing something :-)
I use FFF to fake functions. But I need the pattern above to switch the sources between real-func and faked-func.
I have 3 cases:
Ok, now I got the point. I am currently working on a solution for that, which uses gcc's linker option --wrap to wrap functions. I added additional macros to fff which generates the _wrap fakes with fff and let these fakes use the _real function by default. You can then generate fff-fakes which still use the real function. And you can still spy on the function calls and parameters. Or for some tests you can decide to don't use the real function at all, by changing the *_fake.custom_fake function pointer.
I think it is only working with gcc. At least I am not aware of a similar feature like the --wrap option for other compilers. (But I usually always use gcc, so maybe I am missing something). So when you also use gcc you could try my branch: https://github.com/usr42/fff/tree/wrap_fff It should be working (I added tests and used it for some fakes in a project), but the README in not updated yet. I'll push at least a bullet point documentation to the README to give you a starting point.
Please tell me if are going to test it. Feedback is then more than welcome!
Thanks and regards, Balthasar
I like the gcc --wrap
concept a lot. Integrating that into fff would be perfect. We cross-compile our embedded code - we use gcc for unit tests and IAR for production code. This means a little extra work, but has the added benefit of ensuring from day zero that our code can cross-compile, which helps us isolate any esoteric IAR specific code.
Do you also have a nice pattern for maintaining the --wrap
instructions?
I added a simple and not nearly perfect adaptation in the makefile for fff's tests:
WRAP_LDFLAGS += $(shell grep -r WRAP_FAKE_VALUE_FUNC ./ | grep -v "fff\.h" | grep -v "Makefile" | sed -rn 's/[^,]*,\W*(\w*).*/-Wl,--wrap=\1/p' | sort -u)
WRAP_LDFLAGS += $(shell grep -r WRAP_FAKE_VOID_FUNC ./ | grep -v "fff\.h"| grep -v "Makefile" | sed -rn 's/.*WRAP_FAKE_VOID_FUNC\w*\W*(\w*).*/-Wl,--wrap=\1/p' | sort -u)
...
$(FFF_TEST_CPP_TARGET): $(FFF_TEST_CPP_OBJS)
@echo 'Building target: $@'
@echo 'Invoking: GCC C++ Linker'
g++ -o "$(FFF_TEST_CPP_TARGET)" $(FFF_TEST_CPP_OBJS) $(LIBS) $(WRAP_LDFLAGS)
...
For details see: https://github.com/usr42/fff/blob/wrap_fff/test/Makefile
Is that answering your question?
If you would test my approach/branch and give me feedback, that would be awesome.
One additional note on the --wrap approach: You don't have to adapt the production code at all for that. No cluttering with ifdefs or something similar.
@espenalb Have you already tested the --wrap
approach?
@frankbenoit Is the --wrap
approach working for your purpose?
Hi
i would like to have
fff
to support the dynamic exchange of the functions.Lets say i have a function
foo+bar
and i want to replacy it with my fakes calledfooTest+barTest
. Then i would like to have expanded code like this:In case for working with unittesting, i set the #define UNIT_TESTING
header:
source:
When #define UNIT_TESTING is not set, this expands to:
header:
source:
And this is, how i want to write it:
header:
source:
To implement, this can look like this:
This way, you have function runtime substitution, like you discussed here: https://meekrosoft.wordpress.com/2012/07/20/test-seams-in-c-function-pointers-vs-preprocessor-hash-defines-vs-link-time-substitution/ But the two contra arguments are removed. Now the IDE can resolve the function calls, do auto completion and do code analysis.
Finally, if there would be a way to make the FUNC_IMPL and FUNC_VOID_REDIR a single macro call, this would be super cool. But I don't know how to do that. Perhaps you?
Frank