Header only C++14 mocking framework
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
Go to file
Björn Fahller eaeb89c1ce Updates for v49 2 months ago
.github/workflows CI silence incorrect empty macro warning on clang 10..14 2 months ago
compilation_errors fix: adjust compilation errors 2 months ago
docs Clarified docs on comma in trailing return type 2 months ago
include Fixed off-by-one error in COUNT macro with gcc preprocessor extension 2 months ago
test Trailing return tests 2 months ago
.gitattributes Add gitattributes for line ending normalization 5 years ago
.gitignore Removed conanfile and conan CI builds 4 years ago
CMakeLists.txt Updates for v49 2 months ago
ChangeLog Updates for v49 2 months ago
LICENSE_1_0.txt Initial commit 10 years ago
README.md Updated README with trailing return type examples 2 months ago
_config.yml Fix for Visual Studio 2017 compiler crash -- issue #29 (#38) 8 years ago
check_errors.sh Filter CI compilation error tests on std and compiler 2 years ago
install_libcxx.sh Fix build errors for libcxx-14 2 years ago
trompeloeil-config.cmake versioned cmake package for trompeloeil - yay! 7 years ago
trompeloeil-logo.png Gray logo for dark background 4 years ago
trompeloeil-logo.svg Gray logo for dark background 4 years ago
verify_compilation_error.sh Exclude coroutine tests on MacOS 1 year ago

README.md

Trompeloeil

trompeloeil logo

CI codecov

Get: Conan

Buy me a coffee

trompe l'oeil noun (Concise Encyclopedia) Style of representation in which a painted object is intended to deceive the viewer into believing it is the object itself...

What is it?

A thread-safe header-only mocking framework for C++11/14 using the Boost Software License 1.0

Documentation

Also, follow up with the post on sequencing for examples on how to restrict or relax allowed sequences of matching calls.

Teaser

#include <trompeloeil.hpp>

class Interface
{
public:
  virtual ~Interface() = default;
  virtual bool foo(int, std::string& s) = 0;
  virtual bool bar(int) = 0;
  virtual bool bar(std::string) = 0;
};

void interface_func(Interface*); // function to test

class Mock : public Interface
{
public:
  MAKE_MOCK(foo, auto (int, std::string&) -> bool, override);
  MAKE_MOCK(bar, auto (int) -> bool, override);
  MAKE_MOCK(bar, auto (std::string) -> bool, override);
  MAKE_MOCK0(baz, void()); // not from Interface
};

TEST(exercise_interface_func)
{
  using trompeloeil::_;  // wild card for matching any value
  using trompeloeil::gt; // greater-than match

  Mock m;

  trompeloeil::sequence seq1, seq2;  // control order of matching calls

  int local_var = 0;

  REQUIRE_CALL(m, bar(ANY(int)))     // expect call to m.bar(int)
    .LR_SIDE_EFFECT(local_var = _1)  // set captured variable to value of param
    .RETURN(_1 > 0)                  // return value depending on param value
    .IN_SEQUENCE(seq1)               // must be first match for seq1
    .TIMES(AT_LEAST(1));             // can be called several times

  FORBID_CALL(m, bar(0));            // but m.bar(0) is not allowed

  REQUIRE_CALL(m, bar("word"))       // expect one call to m.bar(std::string)
    .RETURN(true)
    .IN_SEQUENCE(seq2);              // must be first match for seq2

  REQUIRE_CALL(m, foo(gt(2), _))     // expect call to foo(int,std::string&)
    .WITH(_2 == "")                  // with int > 2 and empty string
    .IN_SEQUENCE(seq1, seq2)         // last for both seq1 and seq2
    .SIDE_EFFECT(_2 = "cat")         // and set param string to "cat"
    .RETURN(true);

  interface_func(&m);

  // all the above expectations must be fulfilled here
}

Building and running the self test suite

To build the self test suite run cmake with -DTROMPELOEIL_BUILD_TESTS=yes. Use the options CXX_STANDARD to select which C++ standard to test, and SANITIZE to select sanitizers to build with. Note that the self tests needs a reasonably modern version of CMake. Example:

cmake -B build_dir \
      -D TROMPELOEIL_BUILD_TESTS=yes \
      -D CMAKE_BUILD_TYPE=Debug \
      -D CXX_STANDARD=17 \
      -D SANITIZE=Address,Undefined \
      <trompeloeil source dir>

If the build finds a CMake package for Catch2 it will use that, otherwise it will download a header-only version of Catch2 v2.x.

cmake --build build_dir -t self_test thread_terror custom_recursive_mutex

Then run the built binaries:

./build_dir/self_test && ./build_dir/thread_terror && ./build_dir/custom_recursive_mutex

How to contribute

Contributions are most welcome. For new functionality, please file an issue as an enhancement request first, to get a discussion going about how to best implement it. Also for bugfixes, it is good to file an issue, so that others can see what the problem is and when it's solved. Internal changes are normally not mentioned in the ChangeLog - it should typically reflect what a user can see (however, performance improvements and silencing warnings are visible for users.) Feel free to add your name to the copyright blurb.

Change PR to
Documentation master branch
Trivial bugfixes master branch
Non trivial bugfixes develop branch
Simple new functionality develop branch
Non-trivial new functionality new topic branch

Compiler compatibility

Trompeloeil is known to work with:

  • GCC 4.8.4+, 4.9.3+, 5, 6, 7, 8, 9, 10, 11, 12, 13
  • Clang 3.5, 3.6, 3.7, 3.8, 3.9, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17
  • Visual Studio 2015, 2017, 2019

Latest patch level releases are assumed in the versions listed above.

Further details on C++11 support, platform and library limitations, may be found in

External Tools

Videos

Mocking Modern C++ with Trompeloeil Mocking Modern C++ with Trompeloeil, introduction to Trompeloeil by Björn Fahller from from from Stockholm C++ UG (34m)
Using Trompeloeil, a Mocking Framework for Modern C++ Using Trompeloeil, a Mocking Framework for Modern C++, by Björn Fahller from NDC{Oslo} 2017 (52m) (Slides)
Using Trompeloeil, a Mocking Framework for Modern C++ Using Trompeloeil, a Mocking Framework for Modern C++, Detailed presentation by Björn Fahller from ACCU 2017 (1h25m) (Slides with extra material)
Packporting to the future Backporting to the Future, Detailing the C++11 API and how it came to be, by Andrew Paxie from Pacific++ 2018 (53m) (Slides)