1bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
2bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<html><head>
3bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<title>Cmockery</title>
4bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson</head>
5bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<body>
6bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<h1>Cmockery Unit Testing Framework</h1>
7bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>Cmockery is a lightweight library that is used to author C unit tests.</p>
8bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
9bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<ul>Contents
10bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#Motivation">Motivation</a></li>
11bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#Overview">Overview</a></li>
12bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#TestExecution">Test Execution</a>
13bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#ExceptionHandling">Exception Handling</a></li>
14bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#FailureConditions">Failure Conditions</a></li>
15bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#Assertions">Assertions</a></li>
16bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <ul>
17bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    <li><a href="#AssertMacros">Assert Macros</a></li>
18bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  </ul>
19bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#MemoryAllocation">Dynamic Memory Allocation</a></li>
20bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#MockFunctions">Mock functions</a></li>
21bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <ul>
22bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    <li><a href="#MockFunctionsReturnValues">Return Values</a></li>
23bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    <li><a href="#MockFunctionsCheckingParameters">Checking Parameters</a></li>
24bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  </ul>
25bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#TestState">Test State</a></li>
26bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#Example">Example</a></li>
27bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson</ul>
28bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
29bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a name="Motivation"><h2>Motivation</h2></a>
30bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>There are a variety of C unit testing frameworks available however many of
31bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonthem are fairly complex and require the latest compiler technology.  Some
32bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsondevelopment requires the use of old compilers which makes it difficult to
33bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonuse some unit testing frameworks.  In addition many unit testing frameworks
34bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonassume the code being tested is an application or module that is targeted to
35bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonthe same platform that will ultimately execute the test.  Because of this
36bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonassumption many frameworks require the inclusion of standard C library headers
37bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonin the code module being tested which may collide with the custom or
38bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonincomplete implementation of the C library utilized by the code under test.</p>
39bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
40bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>Cmockery only requires a test application is linked with the standard C
41bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonlibrary which minimizes conflicts with standard C library headers.  Also,
42bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee WilsonCmockery tries avoid the use of some of the newer features of C compilers.</p>
43bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
44bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>This results in Cmockery being a relatively small library that can be used
45bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonto test a variety of exotic code.  If a developer wishes to simply test an
46bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonapplication with the latest compiler then other unit testing frameworks maybe
47bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonpreferable.</p>
48bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
49bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a name="Overview"><h2>Overview</h2></a>
50bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>Cmockery tests are compiled into stand-alone executables and linked with
51bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonthe Cmockery library, the standard C library and module being tested.  Any
52bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonsymbols external to the module being tested should be mocked - replaced with 
53bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonfunctions that return values determined by the test - within the test
54bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonapplication.  Even though significant differences may exist between the target
55bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonexecution environment of a code module and the environment used to test the
56bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsoncode the unit testing is still valid since its goal is to test the logic of a
57bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsoncode modules at a functional level and not necessarily all of its interactions
58bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonwith the target execution environment.</p>
59bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
60bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>It may not be possible to compile a module into a test application without
61bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonsome modification, therefore the preprocessor symbol <b>UNIT_TESTING</b> should
62bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonbe defined when Cmockery unit test applications are compiled so code within the
63bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonmodule can be conditionally compiled for tests.</p>
64bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
65bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a name="TestExecution"><h2>Test Execution</h2></a>
66bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>Cmockery unit test cases are functions with the signature
67bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<b>void function(void **state)</b>.  Cmockery test applications initialize a
68bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsontable with test case function pointers using <b>unit_test*()</b> macros.  This
69bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsontable is then passed to the <b>run_tests()</b> macro to execute the tests.
70bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
71bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<b>run_tests()</b> sets up the appropriate exception / signal handlers and
72bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonother data structures prior to running each test function.   When a unit test
73bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonis complete <b>run_tests()</b> performs various checks to determine whether
74bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonthe test succeeded.</p>
75bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
76bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<h4>Using run_tests()</h4>
77bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<listing>
78bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/run_tests.c">run_tests.c</a>
79bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson-------------------------------------------------------------------------------
80bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stdarg.h&gt;
81bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stddef.h&gt;
82bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;setjmp.h&gt;
83bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;cmockery.h&gt;
84bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
85bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// A test case that does nothing and succeeds.
86bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid null_test_success(void **state) {
87bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
88bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
89bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonint main(int argc, char* argv[]) {
90bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    const UnitTest tests[] = {
91bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(null_test_success),
92bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    };
93bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return run_tests(tests);
94bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
95bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson</listing>
96bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
97bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a name="ExceptionHandling"><h2>Exception Handling</h2></a>
98bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>Before a test function is executed by <b>run_tests()</b>,
99bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonexception / signal handlers are overridden with a handler that simply
100bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsondisplays an error and exits a test function if an exception occurs.  If an
101bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonexception occurs outside of a test function, for example in Cmockery itself,
102bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonthe application aborts execution and returns an error code.</p>
103bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
104bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a name="FailureConditions"><h2>Failure Conditions</h2></a>
105bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>If a failure occurs during a test function that's executed via
106bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<b>run_tests()</b>, the test function is aborted and the application's
107bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonexecution resumes with the next test function.
108bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
109bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee WilsonTest failures are ultimately signalled via the Cmockery function <b>fail()</b>.
110bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee WilsonThe following events will result in the Cmockery library signalling a test
111bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonfailure...
112bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
113bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<ul>
114bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#Assertions">Assertions</a></li>
115bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#ExceptionHandling">Exceptions</a></li>
116bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#MemoryAllocation">Memory leaks</a></li>
117bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#TestState">Mismatched setup and tear down functions</a></li>
118bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#MockFunctionsReturnValues">Missing mock return values</a></li>
119bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#MockFunctionsReturnValues">Unused mock return values</a></li>
120bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#MockFunctionsCheckingParameters">Missing expected parameter
121bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson                                                 values</a></li>
122bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  <li><a href="#MockFunctionsCheckingParameters">Unused expected parameter
123bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson                                                 values</a></li>
124bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson</ul>
125bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson</p>
126bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
127bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a name="Assertions"><h2>Assertions</h2></a>
128bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>Runtime assert macros like the standard C library's <b>assert()</b> should
129bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonbe redefined in modules being tested to use Cmockery's <b>mock_assert()</b>
130bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonfunction.  Normally <b>mock_assert()</b> signals a
131bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="#FailureConditions">test failure</a>.  If a function is called using
132bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonthe <b>expect_assert_failure()</b> macro, any calls to <b>mock_assert()</b>
133bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonwithin the function will result in the execution of the test.  If no
134bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsoncalls to <b>mock_assert()</b> occur during the function called via
135bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<b>expect_assert_failure()</b> a test failure is signalled.</p>
136bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
137bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<h4>Using mock_assert()</h4>
138bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<listing>
139bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/assert_module.c">assert_module.c</a>
140bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson-------------------------------------------------------------------------------
141bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;assert.h&gt;
142bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
143bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// If unit testing is enabled override assert with mock_assert().
144bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#if UNIT_TESTING
145bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern void mock_assert(const int result, const char* const expression, 
146bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson                        const char * const file, const int line);
147bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#undef assert
148bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#define assert(expression) \
149bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    mock_assert((int)(expression), #expression, __FILE__, __LINE__);
150bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#endif // UNIT_TESTING
151bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
152bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid increment_value(int * const value) {
153bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    assert(value);
154bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    (*value) ++;
155bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
156bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
157bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid decrement_value(int * const value) {
158bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    if (value) {
159bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        *value --;
160bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    }
161bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
162bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
163bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/assert_module_test.c">assert_module_test.c</a>
164bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson-------------------------------------------------------------------------------
165bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stdarg.h&gt;
166bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stddef.h&gt;
167bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;setjmp.h&gt;
168bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;cmockery.h&gt;
169bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
170bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern void increment_value(int * const value);
171bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
172bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson/* This test case will fail but the assert is caught by run_tests() and the
173bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson * next test is executed. */
174bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid increment_value_fail(void **state) {
175bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    increment_value(NULL);
176bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
177bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
178bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// This test case succeeds since increment_value() asserts on the NULL pointer.
179bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid increment_value_assert(void **state) {
180bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    expect_assert_failure(increment_value(NULL));
181bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
182bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
183bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson/* This test case fails since decrement_value() doesn't assert on a NULL
184bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson * pointer. */
185bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid decrement_value_fail(void **state) {
186bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    expect_assert_failure(decrement_value(NULL));
187bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
188bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
189bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonint main(int argc, char *argv[]) {
190bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    const UnitTest tests[] = {
191bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(increment_value_fail),
192bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(increment_value_assert),
193bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(decrement_value_fail),
194bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    };
195bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return run_tests(tests);
196bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
197bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson</listing>
198bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
199bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<h3><a name="AssertMacros">Assert Macros</a></h3>
200bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
201bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>Cmockery provides an assortment of assert macros that tests applications
202bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonshould use use in preference to the C standard library's assert macro.  On an
203bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonassertion failure a Cmockery assert macro will write the failure to the
204bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonstandard error stream and signal a test failure.  Due to limitations of the
205bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee WilsonC language the general C standard library assert() and Cmockery's
206bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonassert_true() and assert_false() macros can only display the expression that
207bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsoncaused the assert failure.  Cmockery's type specific assert macros,
208bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonassert_{type}_equal() and assert_{type}_not_equal(), display the data that
209bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsoncaused the assertion failure which increases data visibility aiding
210bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsondebugging of failing test cases.</p>
211bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
212bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<h4>Using assert_{type}_equal() macros</h4>
213bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<listing>
214bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/assert_macro.c">assert_macro.c</a>
215bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson-------------------------------------------------------------------------------
216bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;string.h&gt;
217bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
218bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonstatic const char* status_code_strings[] = {
219bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    "Address not found",
220bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    "Connection dropped",
221bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    "Connection timed out",
222bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson};
223bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
224bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonconst char* get_status_code_string(const unsigned int status_code) {
225bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return status_code_strings[status_code];
226bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson};
227bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
228bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonunsigned int string_to_status_code(const char* const status_code_string) {
229bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    unsigned int i;
230bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    for (i = 0; i < sizeof(status_code_string) / sizeof(status_code_string[0]);
231bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson         i++) {
232bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        if (strcmp(status_code_strings[i], status_code_string) == 0) {
233bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson            return i;
234bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        }
235bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    }
236bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return ~0U;
237bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
238bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
239bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/assert_macro_test.c">assert_macro_test.c</a>
240bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson-------------------------------------------------------------------------------
241bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stdarg.h&gt;
242bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stddef.h&gt;
243bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;setjmp.h&gt;
244bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;cmockery.h&gt;
245bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
246bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern const char* get_status_code_string(const unsigned int status_code);
247bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern unsigned int string_to_status_code(
248bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    const char* const status_code_string);
249bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
250bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson/* This test will fail since the string returned by get_status_code_string(0)
251bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson * doesn't match "Connection timed out". */
252bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid get_status_code_string_test(void **state) {
253bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    assert_string_equal(get_status_code_string(0), "Address not found");
254bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    assert_string_equal(get_status_code_string(1), "Connection timed out");
255bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
256bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
257bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// This test will fail since the status code of "Connection timed out" isn't 1
258bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid string_to_status_code_test(void **state) {
259bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    assert_int_equal(string_to_status_code("Address not found"), 0);
260bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    assert_int_equal(string_to_status_code("Connection timed out"), 1);
261bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
262bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
263bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonint main(int argc, char *argv[]) {
264bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    const UnitTest tests[] = {
265bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(get_status_code_string_test),
266bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(string_to_status_code_test),
267bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    };
268bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return run_tests(tests);
269bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
270bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson</listing>
271bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
272bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a name="MemoryAllocation"><h2>Dynamic Memory Allocation</h2></a>
273bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
274bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>To test for memory leaks, buffer overflows and underflows a module being
275bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsontested by Cmockery should replace calls to <b>malloc()</b>, <b>calloc()</b> and
276bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<b>free()</b> to <b>test_malloc()</b>, <b>test_calloc()</b> and
277bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<b>test_free()</b> respectively.  Each time a block is deallocated using
278bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<b>test_free()</b> it is checked for corruption, if a corrupt block is found
279bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsona <a href="#FailureConditions">test failure</a> is signalled.  All blocks
280bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonallocated using the <b>test_*()</b> allocation functions are tracked by the
281bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee WilsonCmockery library.  When a test completes if any allocated blocks (memory leaks)
282bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonremain they are reported and a test failure is signalled.</p>
283bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>For simplicity Cmockery currently executes all tests in one process.
284bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee WilsonTherefore all test cases in a test application share a single address space
285bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonwhich means memory corruption from a single test case could potentially cause
286bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonthe test application to exit prematurely.</p>
287bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
288bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<h4>Using Cmockery's Allocators</h4>
289bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<listing>
290bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/allocate_module.c">allocate_module.c</a>
291bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson-------------------------------------------------------------------------------
292bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;malloc.h&gt;
293bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
294bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#if UNIT_TESTING
295bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern void* _test_malloc(const size_t size, const char* file, const int line);
296bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern void* _test_calloc(const size_t number_of_elements, const size_t size, 
297bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson                          const char* file, const int line);
298bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern void _test_free(void* const ptr, const char* file, const int line);
299bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
300bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#define malloc(size) _test_malloc(size, __FILE__, __LINE__)
301bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__)
302bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#define free(ptr) _test_free(ptr, __FILE__, __LINE__)
303bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#endif // UNIT_TESTING
304bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
305bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid leak_memory() {
306bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    int * const temporary = (int*)malloc(sizeof(int));
307bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    *temporary = 0;
308bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
309bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
310bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid buffer_overflow() {
311bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    char * const memory = (char*)malloc(sizeof(int));
312bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    memory[sizeof(int)] = '!';
313bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    free(memory);
314bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
315bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
316bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid buffer_underflow() {
317bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    char * const memory = (char*)malloc(sizeof(int));
318bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    memory[-1] = '!';
319bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    free(memory);
320bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
321bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
322bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
323bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/allocate_module_test.c">allocate_module_test.c</a>
324bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson-------------------------------------------------------------------------------
325bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stdarg.h&gt;
326bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stddef.h&gt;
327bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;setjmp.h&gt;
328bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;cmockery.h&gt;
329bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
330bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern void leak_memory();
331bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern void buffer_overflow();
332bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern void buffer_underflow();
333bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
334bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// Test case that fails as leak_memory() leaks a dynamically allocated block.
335bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid leak_memory_test(void **state) {
336bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    leak_memory();
337bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
338bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
339bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// Test case that fails as buffer_overflow() corrupts an allocated block.
340bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid buffer_overflow_test(void **state) {
341bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    buffer_overflow();
342bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
343bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
344bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// Test case that fails as buffer_underflow() corrupts an allocated block.
345bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid buffer_underflow_test(void **state) {
346bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    buffer_underflow();
347bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
348bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
349bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonint main(int argc, char* argv[]) {
350bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    const UnitTest tests[] = {
351bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(leak_memory_test),
352bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(buffer_overflow_test),
353bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(buffer_underflow_test),
354bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    };
355bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return run_tests(tests);
356bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
357bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson</listing>
358bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
359bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a name="MockFunctions"><h2>Mock Functions</h2></a>
360bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
361bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>A unit test should ideally isolate the function or module being tested
362bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonfrom any external dependencies.  This can be performed using mock functions
363bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonthat are either statically or dynamically linked with the module being tested.
364bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee WilsonMock functions must be statically linked when the code being tested directly 
365bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonreferences external functions.  Dynamic linking is simply the process of 
366bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonsetting a function pointer in a table used by the tested module to reference 
367bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsona mock function defined in the unit test.</p>
368bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
369bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a name="MockFunctionsReturnValues"><h3>Return Values</h3></a>
370bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
371bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>In order to simplify the implementation of mock functions Cmockery provides
372bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonfunctionality which stores return values for mock functions in each test
373bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsoncase using <b>will_return()</b>.  These values are then returned by each mock 
374bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonfunction using calls to <b>mock()</b>.
375bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
376bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee WilsonValues passed to <b>will_return()</b> are added to a queue for each function 
377bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonspecified.  Each successive call to <b>mock()</b> from a function removes a
378bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonreturn value from the queue.  This makes it possible for a mock function to use
379bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonmultiple calls to <b>mock()</b> to return output parameters in addition to a
380bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonreturn value.  In addition this allows the specification of return values for 
381bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonmultiple calls to a mock function.</p>
382bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
383bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<h4>Using will_return()</h4>
384bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<listing>
385bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a name="/src/example/database.h" href="database.h">database.h</a>
386bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson-------------------------------------------------------------------------------
387bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsontypedef struct DatabaseConnection DatabaseConnection;
388bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
389bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson/* Function that takes an SQL query string and sets results to an array of
390bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson * pointers with the result of the query.  The value returned specifies the
391bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson * number of items in the returned array of results.  The returned array of
392bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson * results are statically allocated and should not be deallocated using free()
393bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson */
394bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsontypedef unsigned int (*QueryDatabase)(
395bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    DatabaseConnection* const connection, const char * const query_string,
396bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    void *** const results);
397bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
398bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// Connection to a database.
399bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonstruct DatabaseConnection {
400bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    const char *url;
401bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    unsigned int port;
402bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    QueryDatabase query_database;
403bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson};
404bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
405bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// Connect to a database.
406bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee WilsonDatabaseConnection* connect_to_database(const char * const url,
407bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson                                        const unsigned int port);
408bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
409bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
410bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/customer_database.c">customer_database.c</a>
411bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson-------------------------------------------------------------------------------
412bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stddef.h&gt;
413bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stdio.h&gt;
414bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <a href="#database.h">&lt;database.h&gt;</a>
415bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#ifdef _WIN32
416bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#define snprintf _snprintf
417bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#endif // _WIN32
418bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
419bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// Connect to the database containing customer information.
420bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee WilsonDatabaseConnection* connect_to_customer_database() {
421bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return connect_to_database("customers.abcd.org", 321);
422bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
423bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
424bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson/* Find the ID of a customer by his/her name returning a value > 0 if
425bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson * successful, 0 otherwise. */
426bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonunsigned int get_customer_id_by_name(
427bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        DatabaseConnection * const connection,
428bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        const char * const customer_name) {
429bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    char query_string[256];
430bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    int number_of_results;
431bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    void **results;
432bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    snprintf(query_string, sizeof(query_string),
433bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson             "SELECT ID FROM CUSTOMERS WHERE NAME = %s", customer_name);
434bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    number_of_results = connection->query_database(connection, query_string,
435bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson                                                   &results);
436bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    if (number_of_results != 1) {
437bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        return -1;
438bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    }
439bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return (unsigned int)results[0];
440bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
441bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
442bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
443bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/customer_database_test.c">customer_database_test.c</a>
444bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson-------------------------------------------------------------------------------
445bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stdarg.h&gt;
446bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stddef.h&gt;
447bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;setjmp.h&gt;
448bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;cmockery.h&gt;
449bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <a href="#database.h">&lt;database.h&gt;</a>
450bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
451bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
452bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern DatabaseConnection* connect_to_customer_database();
453bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern unsigned int get_customer_id_by_name(
454bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    DatabaseConnection * const connection, const char * const customer_name);
455bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
456bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// Mock query database function.
457bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonunsigned int mock_query_database(
458bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        DatabaseConnection* const connection, const char * const query_string,
459bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        void *** const results) {
460bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    *results = (void**)mock();
461bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return (unsigned int)mock();
462bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
463bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
464bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// Mock of the connect to database function.
465bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee WilsonDatabaseConnection* connect_to_database(const char * const database_url,
466bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson                                        const unsigned int port) {
467bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return (DatabaseConnection*)mock();
468bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
469bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
470bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid test_connect_to_customer_database(void **state) {
471bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    will_return(connect_to_database, 0x0DA7ABA53);
472bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    assert_true(connect_to_customer_database() ==
473bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson                (DatabaseConnection*)0x0DA7ABA53);
474bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
475bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
476bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson/* This test fails as the mock function connect_to_database() will have no
477bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson * value to return. */
478bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid fail_connect_to_customer_database(void **state) {
479bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    will_return(connect_to_database, 0x0DA7ABA53);
480bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    assert_true(connect_to_customer_database() ==
481bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson                (DatabaseConnection*)0x0DA7ABA53);
482bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
483bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
484bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid test_get_customer_id_by_name(void **state) {
485bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    DatabaseConnection connection = {
486bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        "somedatabase.somewhere.com", 12345678, mock_query_database
487bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    };
488bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    // Return a single customer ID when mock_query_database() is called.
489bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    int customer_ids = 543;
490bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    will_return(mock_query_database, &customer_ids);
491bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    will_return(mock_query_database, 1);
492bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    assert_int_equal(get_customer_id_by_name(&connection, "john doe"), 543);
493bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
494bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
495bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonint main(int argc, char* argv[]) {
496bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    const UnitTest tests[] = {
497bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(test_connect_to_customer_database),
498bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(fail_connect_to_customer_database),
499bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(test_get_customer_id_by_name),
500bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    };
501bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return run_tests(tests);
502bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
503bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson</listing>
504bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
505bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a name="MockFunctionsCheckingParameters"><h3>Checking Parameters</h3></a>
506bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>In addition to storing the return values of mock functions, Cmockery
507bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonprovides functionality to store expected values for mock function parameters
508bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonusing the expect_*() functions provided.  A mock function parameter can then
509bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonbe validated using the check_expected() macro.
510bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
511bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>Successive calls to expect_*() macros for a parameter queues values to
512bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsoncheck the specified parameter.  check_expected() checks a function parameter
513bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonagainst the next value queued using expect_*(), if the parameter check fails a
514bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsontest failure is signalled.  In addition if check_expected() is called and
515bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonno more parameter values are queued a test failure occurs.</p>
516bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
517bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<h4>Using expect_*()</h4>
518bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<listing>
519bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/product_database.c">product_database.c</a>
520bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson-------------------------------------------------------------------------------
521bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <a href="#database.h">&lt;database.h&gt;</a>
522bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
523bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// Connect to the database containing customer information.
524bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee WilsonDatabaseConnection* connect_to_product_database() {
525bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return connect_to_database("products.abcd.org", 322);
526bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
527bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
528bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/product_database_test.c">product_database_test.c</a>
529bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson-------------------------------------------------------------------------------
530bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stdarg.h&gt;
531bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stddef.h&gt;
532bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;setjmp.h&gt;
533bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;cmockery.h&gt;
534bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <a href="#database.h">&lt;database.h&gt;</a>
535bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
536bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern DatabaseConnection* connect_to_product_database();
537bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
538bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson/* Mock connect to database function.
539bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson * NOTE: This mock function is very general could be shared between tests
540bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson * that use the imaginary database.h module. */
541bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee WilsonDatabaseConnection* connect_to_database(const char * const url,
542bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson                                        const unsigned int port) {
543bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    check_expected(url);
544bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    check_expected(port);
545bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return (DatabaseConnection*)mock();
546bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
547bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
548bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid test_connect_to_product_database(void **state) {
549bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    expect_string(connect_to_database, url, "products.abcd.org");
550bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    expect_value(connect_to_database, port, 322);
551bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    will_return(connect_to_database, 0xDA7ABA53);
552bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    assert_int_equal(connect_to_product_database(), 0xDA7ABA53);
553bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
554bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
555bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson/* This test will fail since the expected URL is different to the URL that is
556bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson * passed to connect_to_database() by connect_to_product_database(). */
557bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid test_connect_to_product_database_bad_url(void **state) {
558bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    expect_string(connect_to_database, url, "products.abcd.com");
559bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    expect_value(connect_to_database, port, 322);
560bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    will_return(connect_to_database, 0xDA7ABA53);
561bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53);
562bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
563bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
564bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson/* This test will fail since the mock connect_to_database() will attempt to
565bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson * retrieve a value for the parameter port which isn't specified by this
566bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson * test function. */
567bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid test_connect_to_product_database_missing_parameter(void **state) {
568bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    expect_string(connect_to_database, url, "products.abcd.org");
569bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    will_return(connect_to_database, 0xDA7ABA53);
570bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53);
571bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
572bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
573bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonint main(int argc, char* argv[]) {
574bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    const UnitTest tests[] = {
575bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(test_connect_to_product_database),
576bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(test_connect_to_product_database_bad_url),
577bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test(test_connect_to_product_database_missing_parameter),
578bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    };
579bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return run_tests(tests);
580bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
581bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson</listing>
582bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
583bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a name="TestState"><h2>Test State</h2></a>
584bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
585bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>Cmockery allows the specification of multiple setup and tear down functions
586bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonfor each test case.  Setup functions, specified by the <b>unit_test_setup()</b>
587bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonor <b>unit_test_setup_teardown()</b> macros allow common initialization to be
588bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonshared between multiple test cases.  In addition, tear down functions,
589bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonspecified by the <b>unit_test_teardown()</b> or
590bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<b>unit_test_setup_teardown()</b> macros provide a code path that is always
591bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonexecuted for a test case even when it fails.</p>
592bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
593bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<h4>Using unit_test_setup_teardown()</h4>
594bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<listing>
595bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/key_value.c">key_value.c</a>
596bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson-------------------------------------------------------------------------------
597bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stddef.h&gt;
598bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stdlib.h&gt;
599bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;string.h&gt;
600bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
601bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsontypedef struct KeyValue {
602bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    unsigned int key;
603bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    const char* value;
604bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson} KeyValue;
605bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
606bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonstatic KeyValue *key_values = NULL;
607bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonstatic unsigned int number_of_key_values = 0;
608bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
609bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid set_key_values(KeyValue * const new_key_values,
610bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson                    const unsigned int new_number_of_key_values) {
611bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    key_values = new_key_values;
612bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    number_of_key_values = new_number_of_key_values;
613bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
614bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
615bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// Compare two key members of KeyValue structures.
616bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonint key_value_compare_keys(const void *a, const void *b) {
617bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return (int)((KeyValue*)a)->key - (int)((KeyValue*)b)->key;
618bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
619bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
620bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// Search an array of key value pairs for the item with the specified value.
621bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee WilsonKeyValue* find_item_by_value(const char * const value) {
622bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson  unsigned int i;
623bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    for (i = 0; i < number_of_key_values; i++) {
624bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        if (strcmp(key_values[i].value, value) == 0) {
625bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson            return &key_values[i];
626bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        }
627bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    }
628bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return NULL;
629bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
630bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
631bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson// Sort an array of key value pairs by key.
632bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid sort_items_by_key() {
633bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    qsort(key_values, number_of_key_values, sizeof(*key_values),
634bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson          key_value_compare_keys);
635bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
636bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
637bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/key_value_test.c">key_value_test.c</a>
638bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson-------------------------------------------------------------------------------
639bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stdarg.h&gt;
640bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;stddef.h&gt;
641bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;setjmp.h&gt;
642bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;string.h&gt;
643bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include &lt;cmockery.h&gt;
644bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
645bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson/* This is duplicated here from the module setup_teardown.c to reduce the
646bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson * number of files used in this test. */
647bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsontypedef struct KeyValue {
648bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    unsigned int key;
649bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    const char* value;
650bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson} KeyValue;
651bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
652bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid set_key_values(KeyValue * const new_key_values,
653bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson                    const unsigned int new_number_of_key_values);
654bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern KeyValue* find_item_by_value(const char * const value);
655bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonextern void sort_items_by_key();
656bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
657bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonstatic KeyValue key_values[] = {
658bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    { 10, "this" },
659bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    { 52, "test" },
660bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    { 20, "a" },
661bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    { 13, "is" },
662bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson};
663bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
664bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid create_key_values(void **state) {
665bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    KeyValue * const items = (KeyValue*)test_malloc(sizeof(key_values));
666bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    memcpy(items, key_values, sizeof(key_values));
667bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    *state = (void*)items;
668bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    set_key_values(items, sizeof(key_values) / sizeof(key_values[0]));
669bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
670bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
671bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid destroy_key_values(void **state) {
672bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    test_free(*state);
673bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    set_key_values(NULL, 0);
674bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
675bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
676bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid test_find_item_by_value(void **state) {
677bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    unsigned int i;
678bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    for (i = 0; i < sizeof(key_values) / sizeof(key_values[0]); i++) {
679bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        KeyValue * const found  = find_item_by_value(key_values[i].value);
680bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        assert_true(found);
681bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        assert_int_equal(found->key, key_values[i].key);
682bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        assert_string_equal(found->value, key_values[i].value);
683bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    }
684bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
685bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
686bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonvoid test_sort_items_by_key(void **state) {
687bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    unsigned int i;
688bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    KeyValue * const kv = *state;
689bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    sort_items_by_key();
690bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    for (i = 1; i < sizeof(key_values) / sizeof(key_values[0]); i++) {
691bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        assert_true(kv[i - 1].key < kv[i].key);
692bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    }
693bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
694bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
695bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonint main(int argc, char* argv[]) {
696bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    const UnitTest tests[] = {
697bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test_setup_teardown(test_find_item_by_value, create_key_values,
698bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson                                 destroy_key_values),
699bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson        unit_test_setup_teardown(test_sort_items_by_key, create_key_values,
700bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson                                 destroy_key_values),
701bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    };
702bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson    return run_tests(tests);
703bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson}
704bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson</listing>
705bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
706bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a name="Example"><h2>Example</h2></a>
707bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
708bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<p>A small command line calculator
709bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/calculator.c">calculator.c</a> application
710bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonand test application that full exercises the calculator application
711bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<a href="/src/example/calculator_test.c">calculator_test.c</a>
712bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilsonare provided as an example of Cmockery's features discussed in this document.
713bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson</p>
714bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson
715bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<hr>
716bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<address></address>
717bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson<!-- hhmts start --> Last modified: Tue Aug 26 09:33:31 PDT 2008 <!-- hhmts end -->
718bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson</body> </html>
719