SkillAgentSearch skills...

EasyMock

The easy mocking framework for writing unit tests

Install / Use

/learn @lcarlier/EasyMock
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Welcome to EasyMock

<a name="user-content-wie"></a> What is EasyMock ?

EasyMock is a tool which generates mocks of C functions by parsing a header file. The mocks can be configured to return a specific value on a specific call. When the mocked function is called, the input argument can be compared to a specific value to verify that the code calling them gives the correct parameters to the mock.

Mocks are very useful when writing unit tests. Thanks to the mocks, the build of the unit tests remains very small because it cuts the dependencies as soon as possible. Also, mocks can be used to validate that a specific functions calls the dependencies with the correct parameters. Then, mocks can be used to check that the function you are testing processes correctly the data returned by the dependencies.

EasyMock is very flexible to reproduce production scenarios because of its flexibility of configuring the mocks.

EasyMock can be used to mock Linux kernel header files to write unit test for validating a Linux kernel driver. An example on how to do so is available in the simple FIFO kernel module project.

Table of content

  • [What is EasyMock ?][whatIsEasymock]
  • [How to compile EasyMock ?][compileEasymock]
    • [Release vs Debug build][relVsDeb]
    • [Dependencies][dependencies]
      • [Linux][linux]
      • [MacOS][macos]
    • [Compilation steps][compilationSteps]
  • [libEasyMockFramework's API][libEasyAPI]
  • [Create a mock][createAMock]
  • [Generated mocks][genFun]
    • [C functions][genFunC]
    • [C++ functions][genFunCpp]
      • [Free functions][genFunCppFf]
      • [Class member functions][genFunCppCmf]
      • [Comparators][genFunCppCmp]
  • [Using the mocks][usingMock]
    • [C functions and C++ free functions][usingMockCff]
    • [C++ member functions][usingMockCppmf]
  • [Unit tested][ut]
  • [I want to participate in the development of EasyMock][participate]
  • [Restriction][restriction]
  • [Bug report][bugReport]
  • [License of the tool][loft]
  • [License of the generated code][logc]
  • [The final note][finalNote]
  • [Thanks][thanks]

<a name="user-content-htce"></a> How to compile EasyMock ?

EasyMock can be compiled on Linux or macOS x86_64/arm.

<a name="user-content-dependencies"></a> Dependencies

EasyMock uses the following mandatory libraries:

  • libclang
  • libclang-cpp
  • libllvm
  • libctemplate
  • libncurse
  • liboost (system, filesystem)

Additionally, the following optional libraries can be installed to enable printing the backtrace in the error messages:

  • libunwind
  • libdw

The following mandatory tools must be installed:

  • A C/C++ compiler:
    • gcc/g++
    • clang/clang++ (Minimum version 8.0)
  • cmake
  • pkg-config

For generating the documentation, the following tools must be installed:

  • doxygen
  • graphviz

<a name="user-content-linux"></a> Linux

The dependencies can be installed on Ubuntu by using the following command:

sudo apt install \
    g++ \
    clang \
    cmake \
    pkg-config \
    libunwind-dev \
    llvm-dev \
    libclang-dev \
    libclang-cpp-dev \
    libncurses-dev \
    libboost-system-dev \
    libboost-filesystem-dev \
    libctemplate-dev \
    libdw-dev \
    doxygen \
    graphviz

<a name="user-content-macos"></a> MacOS

libunwind and libdw are not available in macOS, as such the backtrace support is not supported on macOS.

The dependencies can be installed can be installed via brew.

brew install cmake \
    pkgconfig \
    ncurses \
    gcc \
    llvm \
    ctemplate \
    doxygen \
    boost

<a name="user-content-compilation-steps"></a> Compilation steps

EasyMock uses CMake as software build management. The commands below can be used to compile the tool. Before copying and pasting those lines in your terminal, make sure first to set the EASYMOCK_SOURCE environment variable to the place where the EasyMock's code is installed.

cd $EASYMOCK_SOURCE
mkdir build #Referred as $EASYMOCK_BUILDDIR below
cd build
cmake ..
make -j $(nproc)

Note: On macOS, the following command cmake ../ -GXcode <rest of parameters> can be used to generate the Xcode project to be opened with Xcode IDE, but the Makefiles work just fine.

When the compilation is finished

  • on Linux:
    • the binary to generate the mock called [EasyMockGenerate][createAMock] is under $EASYMOCK_BUILDDIR/src/easyMockGenerate/src/EasyMockGenerate
    • the shared library to be linked to the unit test called [libEasyMockFramework.so][libEasyAPI] is under $EASYMOCK_BUILDDIR/src/easyMockFramework/src/libEasyMockFramework.so
  • on macOS:
    • the binary to generate the mock called [EasyMockGenerate][createAMock] is under $EASYMOCK_BUILDDIR/src/easyMockGenerate/src/<buildType>/EasyMockGenerate
    • the shared library to be linked to the unit test called [libEasyMockFramework.dylib][libEasyAPI] is under $EASYMOCK_BUILDDIR/src/easyMockFramework/src/<buildType>/libEasyMockFramework.dylib

<a name="user-content-rvdb"></a> Release vs Debug build

If you download the compressed archive of EasyMock, the release build is compiled. The release build produces:

  • [EasyMockGenerate][createAMock] which is the binary which can be used to generate mocks.
  • libEasyMockFramework.so which is a shared library to be linked to the final unit test binary. See the [hello world example][helloWorldExample] for a full example on how to use it.

The debug build is selected when one of the following condition is met

  • the directory $EASYMOCK_SOURCE/.git is present (it can be empty).
  • the directory $EASYMOCK_SOURCE/.hg is present (it can be empty).
  • the following parameter is given to the cmake command: -DCMAKE_BUILD_TYPE=Debug

The debug build passes extra debug compilation flags and takes longer because it also compiles all the [tests][ut]. After the debug build has been built, use the command make check to run all the tests.

<a name="user-content-libeasyapi"></a> libEasyMockFramework's API

The unit test which is using libEasyMockFramework.so should include easyMock.h which is in $EASYMOCK_SOURCE/src/easyMockFramework/include/. A good practice to allow your code to be able to include that header is to use the -I option to point to that directory.

That file defines a set of C api to initialise the EasyMock framework and check that the mocks have been called as expected.

Even though EasyMock is implemented in C++, it was chosen to provide a C API to not force the unit test to be written in C++.

For the ease of accessibility, the documentation has been copied into this page.

See the [hello world example][helloWorldExample] for a full example on how to use them.

/*
 * Initialises EasyMock.
 *
 * This must be called at the beginning of every test case.
 */
void easyMock_init();

/*
 * Checks that EasyMock has reported at least one error.
 *
 * This must be called at the end of a unit test after the function being tested
 * has been called. If an error has happened, the API easyMock_getError* can be
 * used to retrieve the error messages.
 *
 * Returns 1 if no error has happened.
 * Returns 0 if at least an error has happened.
 */
int easyMock_check();

/*
 * Returns all the errors in a single buffer.
 *
 * The buffer can directly be printed to the standard output if needed.
 *
 * The returned buffer must not be freed by the caller.
 */
const char *easyMock_getErrorStr();

/*
 * Returns all the errors in an array of pointer to constant array of characters.
 *
 * The parameter size is an output value which tells how many errors
 * are reported into the array.
 *
 * The returned buffer must not be freed by the caller.
 */
const char ** easyMock_getErrorArr(unsigned int *size);

/*
 * Sets whether the error messages should contain the call stack or not.
 *
 * The default is to print the callstack into the error messages.
 */
void easyMock_printCallStack(bool val);

/*
 * Sets whether the mock should verify if the mocks have been called in the
 * order they have been expected.
 *
 * The default is to check that the mocks have been called in the order they
 * have been expected (via the *_ExpectAndReturn* API)
 */
void easyMock_checkCallsOrder(bool val);

<a name="user-content-cam"></a>Create a mock

A good start to get acquainted with EasyMockGenerate is to look at its help.

# ./EasyMockGenerate -h
Generate mocks to be used into unit tests.

EasyMock takes a header file ('-i') and generate a mocked version of functions declared in that header file in a target directory ('-o').
The tool generates mocks for functions directly declared in the header file. I.e. not coming from other included files.
'--generate-included-functions' option can be used to generate mocks of functions declared in included files.

Parameters not recognised by EasyMock (e.g. -I, -D) are given to the parser responsible for parsing the header file.
The same options used by a Clang compiler are recognised by EasyMock's parser.

Usage:
./EasyMockGenerate [OPTIONS...]

OPTIONS are:
	-i <header>                    Input header file.

	-o <directory>                 Output directory.

	--mock-cpp                     Mock C++ header.

	--cwd <directory>              Change to the directory passed on this parameter before running the parser.
	                               Relative paths given to '-i' and '-o' will be taken from the path given to '--cwd'.

	--mock-only <function>         Mock only the function specified in this parameter.

	--generate-types               Generate the used type instead of including the original header.
	                               When using this option, the original header (i.e. the header given to -i) doesn't
	                               need to be used when compiling the mock.
	                               The generated functions signature will not contain any function attribute unless
	                               the --generate-attribute opti
View on GitHub
GitHub Stars10
CategoryContent
Updated6mo ago
Forks2

Languages

C++

Security Score

82/100

Audited on Sep 17, 2025

No findings