Reputation: 338
I know about the basics about test doubles, mocking, etc. but I'm having problems to test the following
void funA(void) {
/* do some stuff, using mocked functions from 3rd party library */
}
I've written the unit tests for funA()
, checking the good functions were called (using their mocked implementation).
So far, the mocked functions are library functions. This is not my code. I don't want to test their original implementation.
Now, I want to test this function
void funB(void) {
/* do some complicated stuff, and call `funA()` on some situations */
}
How can I be sure my funA
function was called from funB
? I can't add a fake implementation to funA
, I need its production code so it can be tested.
What I am doing now is making sure the mocks that funA
is calling are as I expect them to be. But it's not a good method, because it's like I'm testing funA
all over again, when I just want to make sure funB
does its job.
Upvotes: 1
Views: 188
Reputation: 338
After discussing it (see the comments of the original question), and having a brief forum exchange with James Grenning (one of the author of CppUTest), the main solutions are the following:
funA()
and funB()
I'm not a huge fan of either of the solutions, but it feels like I can't do much more in C. I will eventually go for the multiple binaries solution.
For reference, here is the answer of James Grennings:
You may want to mock A() when testing B().
for example
If I have a message_dispatcher() that reads a command from a serial port via getline(), and getline() uses getc() and getc() uses IORead and IOWrite. I could mock IORead and IOWrite and have a set of horrible tests to test the message_dispatcher().
Or I could test getc() with mock IORead() and IOWrite(), getline() with some kind of fake_getc(), and test message_dispatcher() with fake_getline(). If you only use linker substitution, you would need three tests builds. If you used function pointers you could do one test build. You can mix an match too.
getc() should be tested with link time mocks of IORead and IOWrite because your unit tests never want the real IORead and IOWrite for off-target tests (they may be needed of on-target tests, but those would be integration tests).
There are many possibilities. You could also have some other code getline() and feed it to the dispatcher, removing its dependencies.
Upvotes: 1