# bdd-for-c-mocks ## Usage Suppose you have a library `lib` and an application `app` that uses `lib`. You want to test `app` and you want to mock `lib`'s functions. You can do this by creating a mock header file for `lib` and including it in `app`'s test file. ### `lib.h` This is a reference header file for `lib`. The implementation should be abstracted from us, and we want to be able to mock its behavior. ```c #ifndef LIB_H #define LIB_H int add(int a, int b); void alert(); #endif ``` ### `lib.mock.h` We define mocked behavior for `lib`. `bdd-for-c-mocks` offers a capability to force mock behavior through modes. Note that all mode behaviors should be implemented already. ```c #ifndef LIB_MOCK_H #define LIB_MOCK_H #include mock_modes(add) { ADD_RETURNS_SUM = 0, ADD_RETURNS_CONSTANT_VALUE, }; mock(add) int add(int a, int b) { mock_mode_if(add, ADD_RETURNS_SUM) { // suppose we want to test normal behavior mock_return(add) a + b; } else mock_mode_if(add, ADD_RETURNS_CONSTANT_VALUE) { // maybe an edge case? mock_return(add) 5; } } mock(alert) void alert() { mock_return(alert); } #endif ``` ### `app.h` ```c #ifndef APP_H #define APP_H void math(); #endif ``` ### `app.c` This is a reference implementation of `app`. We want to test the invocations done inside the `math()` function. ```c #include "lib.h" #include "app.h" void math() { int result_a = add(1, 2); int result_b = add(3, 4); if (result_a == result_b) { // this is the edge case! // alert() should be called if the add values are the same alert(); } } ``` ### `app.test.c` This is the test file for `app`. It includes `lib.mock.h` instead of `lib.c`. `lib.h` should still be linked because we are sharing the original function declarations. ```c #include #include "app.h" spec("app") { describe("math") { after_each() { mock_reset(add); } after_each() { mock_reset(alert); } it("calls add") { mock_mode(add, ADD_RETURNS_SUM); mock_set_excepted_calls(math, 2); math(); check( mock_get_expected_calls(math) == mock_get_actual_calls(math), "add was not called." ); } it("calls alert when calls from add return the same values") { mock_mode(add, ADD_RETURNS_CONSTANT_VALUE); math(); check(mock_is_called(alert), "alert was not called."); } } } ```