[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Fundamental question: How to resolve dependencies with mock objects


You might want to implement __fake_foo with a function pointer. This way you can swap the implementation at runtime

int (*current_foo)(char* c) = 0;

int __fake_foo(char* c)
{
	if (current_foo)
		return current_foo(c);
	
	return 42;
}

------------------------------------------------------------------
James Grenning                  Author of TDD for Embedded C
www.wingman-sw.com              http://pragprog.com/titles/jgade/
www.wingman-sw.com/blog
www.twitter.com/jwgrenning


On 21 May 2014, at 7:27, Jakub Hrozek wrote:

Hi,

mock and wrap are two different things. You can mock a function
without the _wrap trick and vice versa. For instance, you can mock a
function like the cmocka example illustrates by providing the full
function prototype and returning the previously prepared return code:
http://git.cryptomilk.org/projects/cmocka.git/tree/example/customer_database_test.c#n38

The wrapping is a linker feature that allows you to trick the linker
into calling _wrap_foo() instead of foo(). You can always call the
"real" foo if you like, by calling __real_foo(). This might be useful
to check if foo() was called in the program under test for instance.
In SSSD we have something like:

bool was_foo_called;

__real_foo(); /* You need the declaration */

__wrap_foo()
{
was_foo_called = true; /* Let the test driver know foo was called */
__real_foo();                 /* Call the original foo function */
}

You can even control whether to call the real foo or some mocked
version based on parameter you pass with will_return in advance. Here
is some example from SSSD:
https://git.fedorahosted.org/cgit/sssd.git/tree/src/tests/cmocka/test_nss_srv.c#n89

I hope this helps.

On Wed, May 21, 2014 at 1:48 PM, Frank Lorenz <lorenz-frank@xxxxxx> wrote:
Hi,

starting to use unit tests for an existing project (embedded C), I currently
try to use cmocka for this.
I have a lot of dependencies (e.g. to hardware) and interfaces to other devices that let me think I require mock objects to do a "simple simulation"
of hardware/interfaces for unit tests.
So I started to integrate cmocka and now have a lack of basic understanding
of the concept:

As far as I understand, I need to implement a wrapper function for every function I want to mock. As an example, for a mock of a function int foo(char* c) I write a function int __wrap_foo ( char* c ) and give
the option "--wrap=foo to the linker.

My question is:
If I want to implement unit tests for two modules A and B, and I want to have a mock version of B for unit test of A and a mock version of A for unit
test of B -- how to implement this?
Because when I implement mock versions of all functions of A and of B and tell the linker to use these "wrappers" instead of the real functions, then my unit test executable will only contain the mock versions of all the functions. The "real" implementation of A and B will not be linked into the
executable and therefore cannot be tested.
Or do I miss something?

best regards,
Frank