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 <stdarg.h> 81bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <stddef.h> 82bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <setjmp.h> 83bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <cmockery.h> 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 <assert.h> 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 <stdarg.h> 166bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <stddef.h> 167bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <setjmp.h> 168bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <cmockery.h> 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 <string.h> 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 <stdarg.h> 242bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <stddef.h> 243bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <setjmp.h> 244bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <cmockery.h> 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 <malloc.h> 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 <stdarg.h> 326bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <stddef.h> 327bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <setjmp.h> 328bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <cmockery.h> 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 <stddef.h> 413bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <stdio.h> 414bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <a href="#database.h"><database.h></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 <stdarg.h> 446bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <stddef.h> 447bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <setjmp.h> 448bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <cmockery.h> 449bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <a href="#database.h"><database.h></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"><database.h></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 <stdarg.h> 531bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <stddef.h> 532bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <setjmp.h> 533bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <cmockery.h> 534bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <a href="#database.h"><database.h></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 <stddef.h> 598bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <stdlib.h> 599bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <string.h> 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 <stdarg.h> 640bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <stddef.h> 641bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <setjmp.h> 642bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <string.h> 643bdd62c531bbdea115a3a7e71bba91c19dd319cc4Heather Lee Wilson#include <cmockery.h> 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