Enable mocking for unit testing a library in C
Asked Answered
I

2

7

In our environment we're encountering a problem regarding mocking functions for our library unit tests. The thing is that instead of mocking whole modules (.c files) we would like to mock single functions.

The library is compiled to an archive file and linked statically to the unit test. Without mocking there isn't any issue.

Now when trying to mock single functions of the library we would get multiple definitions obviously.

My approach now is to use the weak function attribute when compiling/linking the library so that the linker takes the mocked (non-weak) function when linking against the unit test. I already tested it and it seems to work as expected.

The downside of this is that we need many attribute declarations in the code.

My final approach would be to pass some compile or link arguments to the compiler, that every function is automatically declared as a weak symbol.

The question now is: Is there anything to do this in a nice way?

btw: We use clang 8 as a compiler.

Intermigration answered 27/1, 2020 at 13:27 Comment(5)
When you have built the library as an ordinary library with separated object modules, you should be able to provide a single mock function. The linker will use that mock function and not the implementation of the library.Patriotism
Unfortunately not. I get a multiple definitions error. It only works if i declare the library func as a weak symbolIntermigration
Please provide a minimal reproducible example and tell us about your target system. The command lines to build are important, naturally. ;-)Patriotism
Did you check out this question and its answers?Patriotism
Do you need to be able to control which functions are mocked within a single executable at runtime? Or is it sufficient to link a separate test executable for each set of mocks?Boothman
L
0

James Grenning describes several options to solve this problem (http://blog.wingman-sw.com/linker-substitution-in-c-limitations-and-workarounds). The option "function pointer substitution" gives a high degree of freedom. It works as follows: Replace functions by pointers to functions. The function pointers are initialized to point to the original function, but each pointer can be redirected individually to a test double.

This approach allows to have one single test executable where you can still decide for each test case individually for which function you use a test double and for which you use the original function.

It certainly also comes at a price:

  • One indirection for each call. But, if you use link-time-optimization the optimizer will most likely eliminate that indirection again, so this may not be an issue.
  • You make it possible to redirect function calls also in production code. This would certainly be a misuse of the concept, however.
Lilybelle answered 5/2, 2020 at 23:51 Comment(0)
R
0

I would suggest using VectorCAST

https://www.vector.com/us/en/products/products-a-z/software/vectorcast/

I've used, unity/cmock and others for unit testing C in the past, but after a while its vary tedious to manually create these for a language that isnt really built around that concept and is very much a heres a Hammer and Chissel the world is yours approach.

VectorCAST abstracts majority of the manual work that is required with tools like Unity/Cmock, we can get results across a project/module sooner and quicker than we did in the past with the other tools.

Is vectorCAST expensive and very much an enterprise level tool? yes... but its defiantly worth its weight in gold. And thats coming from someone who is very old school, manual approach to software development... just text editors, terminals and commandline debuggers.

VetorCAST handles function pointers and pointers extremely well, stubbing functions is easy as two clicks away. It saved our team alot of time... allowing us to focus on results and reducing the feedback loop of development.

Room answered 18/9, 2022 at 3:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.