[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Fundamental question: How to resolve dependencies with mock objects
[Thread Prev] | [Thread Next]
- Subject: Re: Fundamental question: How to resolve dependencies with mock objects
- From: wp1186628-frank <frank@xxxxxxxxxxxxxxxx>
- Reply-to: wp1186628-frank <frank@xxxxxxxxxxxxxxxx>
- Date: Tue, 27 May 2014 16:44:48 +0200 (CEST)
- To: "cmocka@xxxxxxxxxxxxxx" <cmocka@xxxxxxxxxxxxxx>
Hi James, looks like I wrote the mail to early. Chapter 9 of your book covers this topic... best regards, Frank > wp1186628-frank <frank@xxxxxxxxxxxxxxxx> hat am 27. Mai 2014 um 08:50 > geschrieben: > > Hi James, hi Jakub, > > thanks for the feedback. I misunderstood that I do not need wrapping to mock > objects. > > James: At the moment I read your book, currently at chapter 8. Up to now, you > only describe how to replace interaction to Hardware / OS, i.e. mock external > modules that are not part of your project and you do not need to unit test at > all. > But if I have a big system (with complex dependencies between its like > typical for legacy code) and you want to unit test all the modules, I'm not > really sure how to handle this. If I do use function pointers like you > describe I fear ending up with a really complex and hard to understand test > system, continously switching between fake and real implementation. > > More concrete, a first step I want to take is to implement Unit Tests for a > Model-View-Controller implementation (in C). If I want to test each of the > three modules seperately (M, V and C), I will need flexiblity to change > between fake and real implementation for each of the three. So is the only way > to do this "function pointer thing" to achieve this? Is cmocka the right > framework for this or are there frameworks available that can do this nicely? > > best regards, > Frank > > > > > > > James Grenning <james@xxxxxxxxxxxx> hat am 21. Mai 2014 um 15:32 > > > geschrieben: > > > > > > Markdown settings messed with my example code. Here it is again > > > > int (current_foo)(char c) = 0; > > > > int _fakefoo(char* c) > > { > > if (currentfoo) > > return currentfoo(c); > > > > return 42; > > > > } > > > > On 21 May 2014, at 7:47, James Grenning wrote: > > > > > > > > > > You might want to implement _fakefoo with a function pointer. This > > > way you can swap the implementation at runtime > > > > > > int (current_foo)(char c) = 0; > > > > > > int _fakefoo(char* c) > > > { > > > if (currentfoo) > > > return currentfoo(c); > > > > > > return 42; > > > > > > } > > > > > > > > > --------------------------------------------- > > > > > > James Grenning Author of TDD for Embedded C > > > <http://www.wingman-sw.com> > > > http://pragprog.com/titles/jgade/ > > > <http://www.wingman-sw.com/blog> > > > > > > <http://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/customerdatabase_test.c#n38 > > > > > > > > The wrapping is a linker feature that allows you to trick the > > > > linker > > > > into calling wrapfoo() instead of foo(). You can always call > > > > the > > > > "real" foo if you like, by calling _realfoo(). This might be > > > > useful > > > > to check if foo() was called in the program under test for > > > > instance. > > > > In SSSD we have something like: > > > > > > > > bool wasfoocalled; > > > > > > > > _realfoo(); /* You need the declaration */ > > > > > > > > _wrapfoo() > > > > { > > > > wasfoocalled = true; /* Let the test driver know foo was > > > > called / > > > > _realfoo(); / 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 willreturn in > > > > advance. Here > > > > is some example from SSSD: > > > > > > > > https://git.fedorahosted.org/cgit/sssd.git/tree/src/tests/cmocka/testnss_srv.c#n89 > > > > > > > > I hope this helps. > > > > > > > > On Wed, May 21, 2014 at 1:48 PM, Frank Lorenz > > > > lorenz-frank@xxxxxx <mailto: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 _wrapfoo ( 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 > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
Re: Fundamental question: How to resolve dependencies with mock objects | "James Grenning" <james@xxxxxxxxxxxx> |
Fundamental question: How to resolve dependencies with mock objects | "Frank Lorenz" <lorenz-frank@xxxxxx> |
Re: Fundamental question: How to resolve dependencies with mock objects | Jakub Hrozek <jakub.hrozek@xxxxxxxxx> |
Re: Fundamental question: How to resolve dependencies with mock objects | "James Grenning" <james@xxxxxxxxxxxx> |
Re: Fundamental question: How to resolve dependencies with mock objects | "James Grenning" <james@xxxxxxxxxxxx> |
Re: Fundamental question: How to resolve dependencies with mock objects | wp1186628-frank <frank@xxxxxxxxxxxxxxxx> |