trompeloeil

FORK: Header only C++14 mocking framework
git clone https://git.neptards.moe/u3shit/trompeloeil.git
Log | Files | Refs | README

FAQ.md (24913B)


      1 # FAQ
      2 
      3 - Q. [Why a name that can neither be pronounced nor spelled?](#why_name)
      4 - Q. [Which compilers supports *Trompeloeil*?](#compilers)
      5 - Q. [How do I use *Trompeloeil* with XXX unit test framework?](#unit_test_adaptation)
      6 - Q. [Is *Trompeloeil* thread-safe?](#thread_safety)
      7 - Q. [Can a mock function be marked `override`?](#override)
      8 - Q. [Why can't I **`.RETURN()`** a reference?](#return_reference)
      9 - Q. [Why can't I change a local variable in **`.SIDE_EFFECT()`**?](#change_side_effect)
     10 - Q. [Why the "local reference" **`.LR_*()`** variants? Why not always capture by reference?](#why_lr)
     11 - Q. [Is it possible to allow all calls to all mocked functions for all mock objects?](#allow_all)
     12 - Q. [Why are parameters referenced by position and not by name?](#why_pos)
     13 - Q. [Why the need to provide the number of parameters in **`MAKE_MOCKn()`** when all information is in the signature?](#why_param_count)
     14 - Q. [Why *`C++14`* and not *`C++11`* or *`C++03`* that is more widely spread?](#why_cpp14)
     15 - Q. [Why are my parameter values printed as hexadecimal dumps in violation reports](#why_hex)
     16 - Q. [Can I mock a C function API?](#func_mock)
     17 - Q. [Can I match a value pointed to by a pointer parameter?](#match_deref)
     18 - Q. [Can I negate the effect of a matcher?](#negate_matcher)
     19 - Q. [Can I check if an expectation is fulfilled?](#query_expectation)
     20 - Q. [What does it mean to mix **`IN_SEQUENCE`** and **`TIMES`**?](#sequence_times)
     21 - Q. [How do I use *Trompeloeil* in a CMake project?](#cmake)
     22 - Q. [Why are mock objects not move constructible?](#move_constructible)
     23 - Q. [Why can't I mock a function that returns a template?](#return_template)
     24 - Q. [Can I mock a `noexcept` function?](#mock_noexcept)
     25 - Q. [What does it mean that an expectation is "saturated"?](#saturated_expectation)
     26 
     27 ## <A name="why_name"/>Q. Why a name that can neither be pronounced nor spelled?
     28 
     29 **A.** It's a parallel to arts.
     30 [Trompe-l'œil](https://en.wikipedia.org/wiki/Trompe-l%27%C5%93il), which
     31 literally means "trick the eye," refers to an art form where the artist
     32 creates something that tricks the viewer into thinking they see something
     33 other than what is there. Writing mocks for testing has resemblances to
     34 creating Trompe-l'œil art, in that you create mocks that
     35 "tricks" the test object as if it was interacting with the intended
     36 real world. When you use mocks in a test program, you are the Trompe-l'œil
     37 artist, tricking the code under test.
     38 
     39 Perhaps *Illusionist* or *Puppeteer* would have sufficed as names, but
     40 they were taken many times over for other projects, and besides, the author
     41 has a soft spot for Trompe-l'œil art.
     42 
     43 If you **really** cannot handle the name, you can use the following
     44 renaming mechanism. Assume that you'd like the name
     45 [`chimera`](http://www.merriam-webster.com/dictionary/chimera) instead.
     46 
     47 Create a file `chimera.hpp` with the following contents:
     48 
     49 ```Cpp
     50 #ifndef CHIMERA_HPP
     51 #define CHIMERA_HPP
     52 
     53 #include <trompeloeil.hpp>
     54 namespace chimera = trompeloeil;
     55 
     56 #endif /* include guard */
     57 ```
     58 
     59 Your tests can now `#include <chimera.hpp>` and use (for example)
     60 `chimera::expectation` and `chimera::deathwatched<T>`.
     61 
     62 ## <A name="compilers"/>Q. Which compilers supports *Trompeloeil*?
     63 
     64 **A.** *Trompeloeil* is known to work well with:
     65 
     66 - [g\+\+](http://gcc.gnu.org) 4.9.3 and later.
     67 - [clang\+\+](http://clang.llvm.org) 3.5 and later.
     68 - [VisualStudio](http://visualstudio.com) 2015 and later.
     69 
     70 *Trompeloeil* is known to work somewhat with *g\+\+* 4.8.4 and 4.8.5, and
     71 somewhat less with *g\+\+* 4.8.3.  *`g++ 4.8.x`* only compiles with a
     72 C\+\+11 dialect (e.g. *`-std=c++11`*).  For details, see
     73 ["G\+\+ 4.8.x limitations"](Backward.md/#gxx48x_limitations).
     74 
     75 ## <A name="unit_test_adaptation"/>Q. How do I use *Trompeloeil* with XXX unit test framework?
     76 
     77 **A.** By default, *Trompeloeil* reports violations by throwing an exception,
     78 explaining the problem in the
     79 [`what()`](http://en.cppreference.com/w/cpp/error/exception/what) string.
     80 
     81 Depending on your test frame work and your runtime environment, this may,
     82 or may not, suffice.
     83 
     84 *Trompeloeil* offers support for adaptation to any test frame work. Adaptation
     85 examples for some popular unit test frame works are listed in the
     86 [Cook Book](CookBook.md/#unit_test_frameworks).
     87 
     88 ## <A name="thread_safety"/>Q. Is *Trompeloeil* thread-safe?
     89 
     90 **A.** Yes, with caveats.
     91 
     92 In a unit test you don't want to depend on the scheduler, which is typically
     93 out of your control. However, some times it is convenient to use a unit test
     94 like environment to exercise a larger aspect of your code. In this setting,
     95 using [mock objects](reference.md/#mock_object) with different
     96 [expectations](reference.md/#expectation) can make sense when statistically
     97 searching for synchronization problems.
     98 
     99 To enable this, *Trompeloeil* uses a global
    100 [`recursive_mutex`](http://en.cppreference.com/w/cpp/thread/recursive_mutex)
    101 which protects [expectations](reference.md/#expectation).
    102 
    103 [Expectations](reference.md/#expectation) can come and go in different threads,
    104 and [mock functions](reference.md/#mock_function) can be called in different
    105 threads, all protected by the global lock. However, it is essential that the
    106 [mock object](reference.md/#mock_object) is not deleted while establishing the
    107 [expectation](reference.md/#expectation) or calling the
    108 [mock function](reference.md/#mock_function), as per normal thread-safety
    109 diligence.
    110 
    111 Should you need to access the lock in your tests, you can do so with
    112 
    113 ```Cpp
    114   auto lock = trompeloeil::get_lock();
    115 ```
    116 
    117 `lock` holds the
    118 [`recursive_mutex`](http://en.cppreference.com/w/cpp/thread/recursive_mutex)
    119 until it goes out of scope.
    120 
    121 ## <A name="override"/>Q. Can a mock function be marked `override`?
    122 
    123 **A.** Yes, just add `override` a third parameter to
    124 [**`MAKE_MOCKn()`**](reference.md/#MAKE_MOCKn) or
    125 [**`MAKE_CONST_MOCKn()`**](reference.md/#MAKE_CONST_MOCKn)
    126 
    127 Example:
    128 
    129 ```Cpp
    130 class Interface
    131 {
    132 public:
    133   virtual ~Interface() = default;
    134   virtual int func1(int) = 0;
    135 };
    136 
    137 class Mock : public Interface
    138 {
    139 public:
    140   MAKE_MOCK1(func1, int(int), override); // overridden
    141   MAKE_MOCK1(func2, int(int));           // not overridden
    142 };
    143 ```
    144 
    145 ## <A name="return_reference"/>Q. Why can't I [**`.RETURN()`**](reference.md/#RETURN) a reference?
    146 
    147 **A.** You can, but the language is a bit peculiar.
    148 
    149 For parameters or returned references from function calls, just use
    150 **`.RETURN(value)`**. For local variables you need
    151 [**`.LR_RETURN()`**](reference.md/#LR_RETURN), and for both global and local
    152 variables you either need to use
    153 [`std::ref(value)`](http://en.cppreference.com/w/cpp/utility/functional/ref) or
    154 [`std::cref(value)`](http://en.cppreference.com/w/cpp/utility/functional/cref)
    155 for it, or just enclose the value in an extra parenthesis, like this
    156 [**`.LR_RETURN((value))`**](reference.md/#LR_RETURN)
    157 
    158 Example:
    159 
    160 ```Cpp
    161 class C
    162 {
    163 public:
    164   MAKE_MOCK1(lookup, std::string&(int));
    165 };
    166 
    167 using trompeloeil::_;
    168 using trompeloeil::lt;
    169 
    170 TEST(some_test)
    171 {
    172   C mock_obj;
    173 
    174   std::map<int, std::string> dictionary{ {...} };
    175 
    176   std::string default_string;
    177 
    178   ALLOW_CALL(mock_obj, lookup(_))
    179     .LR_RETURN(dictionary.at(_1)); // function call
    180 
    181   ALLOW_CALL(mock_obj, lookup(trompeloeil::lt(0)))
    182     .LR_RETURN((default_string)); // extra parenthesis
    183 
    184   ALLOW_CALL(mock_obj, lookup(0))
    185     .LR_RETURN(std::ref(default_string));
    186 
    187   test_func(&mock_obj);
    188 }
    189 ```
    190 
    191 Above, the [expectations](reference.md/#expectation) on function
    192 `lookup()` is that any call is allowed and will return an
    193 [lvalue-reference](http://en.cppreference.com/w/cpp/language/reference)
    194 to either a match in  `dictionary`, or to the local variable
    195 `default_string`. The reference is non-const, so `test_func()` is allowed to
    196 change the returned string.
    197 
    198 ## <A name="change_side_effect"/> Q. Why can't I change a local variable in [**`.SIDE_EFFECT()`**](reference.md/#SIDE_EFFECT)?
    199 
    200 **A.** It would almost certainly be very confusing. All local variables
    201 referenced in [**`.WITH()`**](reference.md/#WITH),
    202 [**`.SIDE_EFFECT()`**](reference.md/#SIDE_EFFECT),
    203 [**`.RETURN()`**](reference.md/#RETURN) and
    204 [**`.THROW()`**](reference.md/#THROW)
    205 are captured by value, i.e. each such clause has its own copy of the local
    206 variable. If you could change it, it would change the value in that clause
    207 only and not in any of the others.
    208 
    209 Example:
    210 
    211 ```Cpp
    212 class C
    213 {
    214 public:
    215   MAKE_MOCK1(func, void(int));
    216 };
    217 
    218 using trompeloeil::_;
    219 
    220 TEST(some_test)
    221 {
    222   C mock_obj;
    223 
    224   unsigned abs_sum = 0;
    225 
    226   ALLOW_CALL(mock_obj, func(trompeloeil::gt(0)))
    227     .SIDE_EFFECT(abs_sum+= _1); // illegal code!
    228 
    229   ALLOW_CALL(mock_obj, func(trompeloeil::lt(0))
    230     .SIDE_EFFECT(abs_sum-= _1); // illegal code!
    231 
    232   ALLOW_CALL(mock_obj, func(0));
    233 
    234   test_func(&mock_obj);
    235 ```
    236 
    237 The two [**`SIDE_EFFECT()`**](reference.md/#SIDE_EFFECT) clauses above
    238 each have their own copy of the local variable `abs_sum`. Allowing them
    239 to update their own copies would be very confusing, and it would also be
    240 difficult to get the value back to the test.
    241 
    242 If you need to change the value of a local variable it is better to
    243 use the alternative "local reference" forms
    244 [**`LR_SIDE_EFFECT()`**](reference.md/#LR_SIDE_EFFECT),
    245 [**`LR_WITH()`**](reference.md/#LR_WITH),
    246 [**`LR_RETURN()`**](reference.md/#LR_RETURN) or
    247 [**`LR_THROW()`**](reference.md/#LR_THROW).
    248 
    249 ## <A name="why_lr"/> Q. Why the "local reference" **`.LR_*()`** variants? Why not always capture by reference?
    250 
    251 **A.** It's safer. Lifetime management can be tricky in *`C++`*, and even more
    252 so when complex functionality is hiding behind hideous macros in a
    253 frame work. Experiences from the alpha phase, where this distinction wasn't
    254 made, made the problem glaringly obvious. Making the default safe, and
    255 providing the option to very visibly use the potentially unsafe, is
    256 considerably better, although it makes the test code somewhat visually
    257 unpleasant.
    258 
    259 ## <A name="allow_all"/> Q. Is it possible to allow all calls to all mocked functions for all mock objects?
    260 
    261 **A.** No, it is not. There are two reasons for this, technical and philosophical.
    262 
    263 **Technical** There is a problem with the return value. It is difficult, if
    264 at all possible, to come up with a generic return that works for all types.
    265 This could be overcome by allowing all calls to all functions with a certain
    266 return type, for all objects.
    267 
    268 **Philosophical** While there are no doubt situations where this would be
    269 convenient, it could be a very dangerous convenience that opens up for
    270 relaxing tests unnecessarily, simply because it's so easy to allow
    271 everything, and then when you introduce a bug, you never notice
    272 because everything is allowed. If a safe way of allowing all calls is
    273 thought of, then this may change, but having a perhaps unnecessarily strict
    274 rule that can be relaxed is safer than the alternative.
    275 
    276 ## <A name="why_pos"/> Q. Why are parameters referenced by position and not by name?
    277 
    278 **A.** If you can figure out a way to refer to parameters by name, please
    279 [open an issue](https://github.com/rollbear/trompeloeil/issues) discussing the
    280 idea. If you can provide a pull request, so much the better.
    281 
    282 ## <A name="why_param_count"/> Q. Why the need to provide the number of parameters in [**`MAKE_MOCKn()`**](reference.md/#MAKE_MOCKn) when all information is in the signature?
    283 
    284 **A.** If you can figure out a way to infer the information necessary to
    285 generate a mocked implementation without an explicit parameter count,
    286 please [open an issue](https://github.com/rollbear/trompeloeil/issues)
    287 discussing the idea. If you can provide a pull request, so much the better.
    288 
    289 ## <A name="why_cpp14"/> Q. Why *`C++14`* and not *`C++11`* or *`C++03`* that is more widely spread?
    290 
    291 **A.** *`C++03`* and older is completely out. The
    292 functionality needed for *Trompeloeil* isn't there.
    293 [Lambdas](http://en.cppreference.com/w/cpp/language/lambda) and
    294 [variadic templates](http://en.cppreference.com/w/cpp/language/parameter_pack)
    295 are absolutely necessary.
    296 
    297 The only thing "needed" that *`C++11`* doesn't provide is
    298 [generic lambdas](https://en.wikipedia.org/wiki/C%2B%2B14#Generic_lambdas).
    299 It is perhaps possible that "needed" is too strong a word, that it is
    300 in fact possible without them, in which case a back port to *`C++11`* could be
    301 made.
    302 
    303 And indeed, since this FAQ question was first answered, a back port of a
    304 useful subset of Trompeloeil has been completed for use with *`C++11`*.
    305 For details, see ["Backward compatibility with earlier versions of C\+\+"](
    306   Backward.md
    307 ).
    308 
    309 ## <A name="why_hex"/> Q. Why are my parameter values printed as hexadecimal dumps in violation reports?
    310 
    311 **A.** By default *Trompeloeil* prints parameter values using the
    312 [stream insertion operators](http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt)
    313 for the type, but if none exists, it presents a hexadecimal dump of the memory
    314 occupied by the value.
    315 
    316 You can change that either by providing a stream insertion operator for your
    317 type, or by providing a [custom formatter](CookBook.md/#custom_formatting)
    318 for it.
    319 
    320 ## <A name="func_mock"/> Q. Can I mock a C function API?
    321 
    322 **A.** *Trompeloeil* can mock member functions only. However, there are
    323 tricks you can use to mock a function API, provided that it is OK
    324 to use a
    325 [link seam](http://www.informit.com/articles/article.aspx?p=359417&seqNum=3)
    326 and link your test program with a special test
    327 implementation of the API that calls mocks. Here's an example:
    328 
    329 ```Cpp
    330 /* c_api.h */
    331 #ifdef __cplusplus
    332 extern "C" {
    333 #endif
    334 
    335 int func1(const char*);
    336 const char* func2(int);
    337 
    338 #ifdef __cplusplus
    339 }
    340 #endif
    341 ```
    342 
    343 With the above C-API mocks can be made:
    344 
    345 ```Cpp
    346 /* mock_c_api.h */
    347 #ifndef MOCK_C_API_H
    348 #define MOCK_C_API_H
    349 
    350 #include <c_api.h>
    351 #include <cassert>
    352 #include <string>
    353 #include <trompeloeil.hpp>
    354 
    355 struct mock_api
    356 {
    357   static mock_api*& instance() { static mock_api* obj = nullptr; return obj; }
    358   mock_api() { assert(instance() == nullptr); instance() = this; }
    359   ~mock_api() { assert(instance() == this); instance() = nullptr; }
    360   mock_api(const mock_api&) = delete;
    361   mock_api& operator=(const mock_api&) = delete;
    362 
    363   MAKE_CONST_MOCK1(func1, int(std::string)); // strings are easier to deal with
    364   MAKE_CONST_MOCK1(func2, const char*(int));
    365 };
    366 
    367 endif /* include guard */
    368 ```
    369 
    370 Note that the mock constructor stores a globally available pointer to the
    371 instance, and the destructor clears it.
    372 
    373 With the mock available the test version the C-API can easily be implemented:
    374 
    375 ```Cpp
    376 #include "mock_c_api.h"
    377 
    378 int func1(const char* str)
    379 {
    380   auto obj = mock_api::instance();
    381   assert(obj);
    382   return obj->func1(str); // creates a std::string
    383 }
    384 
    385 const char* func2(int value)
    386 {
    387   auto obj = mock_api::instance();
    388   assert(obj);
    389   return obj->func2(value);
    390 }
    391 ```
    392 
    393 Now your tests becomes simple:
    394 
    395 ```Cpp
    396 #include "mock_c_api.h"
    397 #include "my_obj.h"
    398 TEST("my obj calls func1 with empty string when poked")
    399 {
    400   mock_api api;
    401   my_obj tested;
    402   {
    403     REQUIRE_CALL(api, func1(""))
    404       .RETURN(0);
    405     tested.poke(0);
    406   }
    407 }
    408 ```
    409 
    410 ## <A name="match_deref"/> Q. Can I match a value pointed to by a pointer parameter?
    411 
    412 **A.** You can always match with [**`_`**](reference.md/#wildcard)
    413 and use [**`LR_WITH()`**](reference.md/#LR_WITH) or
    414 [**`WITH()`**](reference.md/#WITH) using whatever logic you
    415 like. But by using [matchers](CookBook.md/#matching_conditions)
    416 you can match the value pointed to using unary operator
    417 [**`*`**](reference.md/#deref_matcher) on the *matcher*.
    418 
    419 See [Matching pointers to values](CookBook.md/#matching_pointers)
    420 in the [Cook Book](CookBook.md).
    421 
    422 ## <A name="negate_matcher"/> Q. Can I negate the effect of a matcher?
    423 
    424 **A.** You can always match with [**`_`**](reference.md/#wildcard)
    425 and use [**`LR_WITH()`**](reference.md/#LR_WITH) or
    426 [**`WITH()`**](reference.md/#WITH) using whatever logic you
    427 like. But by using [matchers](CookBook.md/#matching_conditions)
    428 you can negate the effect of the matcher, allowing what the
    429 matcher disallows and vice versa, using operator
    430 [**`!`**](reference.md/#negate_matcher) on the *matcher*.
    431 
    432 See [Matching the opposite of a matcher](CookBook.md/#negating_matchers)
    433 in the [Cook Book](CookBook.md).
    434 
    435 ## <A name="query_expectation"/> Q. Can I check if an expectation is fulfilled?
    436 
    437 Yes, if you use [**`NAMED_ALLOW_CALL(...)`**](reference.md/#NAMED_ALLOW_CALL),
    438 [**`NAMED_REQUIRE_CALL(...)`**](reference.md/#NAMED_REQUIRE_CALL) or
    439 [**`NAMED_FORBID_CALL(...)`**](reference.md/#NAMED_FORBID_CALL), then you can
    440 ask [`is_satisfied()`](reference.md/#is_satisfied) and
    441 [`is_saturated()`](reference.md/#is_saturated). Example:
    442 
    443 ```Cpp
    444 TEST("something")
    445 {
    446   mock_obj mock;
    447   auto ptr = NAMED_REQUIRE_CALL(mock, some_func())
    448                .TIMES(2,4);
    449   ...
    450   if (ptr->is_satisfied()) // at least two call have been made
    451   ...
    452   if (ptr->is_saturated()) // four calls have been made
    453 }
    454 ```
    455 
    456 Likewise you can ask [sequence objects](reference.md/#sequence_type) if the
    457 sequence they describe [`is_completed()`](reference.md/#is_completed).
    458 
    459 These are rarely useful in pure unit tests, but it can be useful for mini
    460 integration tests, especially when threading is involved.
    461 
    462 ## <A name="sequence_times"/>Q. What does it mean to mix **`IN_SEQUENCE`** and **`TIMES`**?
    463 
    464 **A.** Using [**`.TIMES()`**](reference.md/#TIMES) with
    465 [**`.IN_SEQUENCE()`**](reference.md/#IN_SEQUENCE) is confusing at best, and
    466 especially when you have a (possibly open) interval for **`.TIMES()`**.
    467 
    468 Trompeloeil always sees sequences as observed from a sequence object, and a
    469 sequence object can only move forward in what it allows.
    470 
    471 Example:
    472 
    473 ```Cpp
    474 trompeloeil::sequence seq;
    475 REQUIRE_CALL(mock, foo1)
    476   .TIMES(AT_LEAST(1))
    477   .IN_SEQUENCE(seq);
    478 REQUIRE_CALL(mock, foo2)
    479   .IN_SEQUENCE(seq);
    480 REQUIRE_CALL(mock, foo3)
    481   .IN_SEQUENCE(seq);
    482 
    483 // later...
    484 
    485 mock.foo1();
    486 mock.foo2();
    487 mock.foo1(); // boom!
    488 mock.foo3();
    489 ```
    490 
    491 In the example above, a sequence violation is reported on the second call to
    492 `mock.foo1()`. It goes like this:
    493 
    494 `mock.foo1();`
    495 this is the first call for the sequence object, so it is allowed. It says
    496 **`AT_LEAST(1)`**, so it may move to the next step, or it may repeat the same
    497 call.
    498 
    499 `mock.foo2();`
    500 The current step in the sequence is `mock.foo1()`, but it is satisfied, so moving on
    501 to the next one is allowed. The next one is `mock.foo2()`, which matches this call,
    502 so everything is good.
    503 
    504 `mock.foo1();`
    505 The current step in the sequence is `mock.foo2()`. Is is satisfied and
    506 saturated, so the sequence object must move to the next step. The next step is
    507 `mock.foo3()`, which is a mismatch, so a sequence violation is reported.
    508 
    509 ## <A name="cmake"/>Q. How do I use *Trompeloeil* in a CMake project?
    510 
    511 **A.** To use *Trompeloeil* in a project that is built with CMake, there are several
    512 options to make it accessible to CMake. (The commands below of for Linux, but it works
    513 similarly on other platforms.)
    514 
    515 First, you could build and install it locally somewhere in your project (here,
    516 in `./my_proj/toolkits`):
    517 
    518 ```cmake
    519 git clone https://github.com/rollbear/trompeloeil.git
    520 cd trompeloeil
    521 mkdir build ; cd build
    522 cmake -G "Unix Makefiles" .. -DCMAKE_INSTALL_PREFIX=../../my_proj/toolkits
    523 cmake --build . --target install
    524 ```
    525 
    526 This will create a directory structure inside `toolkits` that has `include/trompeloeil.hpp`
    527 and the CMake find modules in `lib/cmake/trompeloeil`. Whether you add the entire *Trompeloeil*
    528 repo to your source control is up to you, but the minimal set of files for proper CMake
    529 support in is in the `toolkits` directory.
    530 
    531 Second, you could install it globally on your system by cloning the repo and installing with
    532 root privileges:
    533 
    534 ```cmake
    535 git clone https://github.com/rollbear/trompeloeil.git
    536 cd trompeloeil
    537 mkdir build ; cd build
    538 cmake -G "Unix Makefiles" ..
    539 sudo cmake --build . --target install
    540 ```
    541 
    542 In either case, add a `find_package()` call in your project's `CMakeLists.txt`:
    543 
    544 ```cmake
    545 find_package( Catch2      REQUIRED HINTS "${toolkitsDir}/Catch2"      ) # Sample unit test framework
    546 find_package( trompeloeil REQUIRED HINTS "${toolkitsDir}/trompeloeil" )
    547 
    548 add_executable( my_unit_tests
    549     test1.cpp
    550     test2.cpp
    551     test_main.cpp
    552 )
    553 
    554 target_link_libraries( my_unit_tests
    555     my_library_under_test # provided by an add_library() call elsewhere in your project
    556 
    557     # Nothing to link since both of these libs are header-only,
    558     # but this sets up the include path correctly too
    559     Catch2::Catch2
    560     trompeloeil::trompeloeil
    561 )
    562 
    563 # Optional: Use CTest to manage your tests
    564 add_test( run_my_unit_tests my_unit_tests ) # May need to call enable_testing() elsewhere also
    565 ```
    566 
    567 This assumes that you have defined a variable called `toolkitsDir` pointing to
    568 `my_proj/toolkits/lib/cmake`, that you have Catch2 installed similarly, and
    569 that you have defined a target called `my_library_under_test` in other parts of
    570 the CMake files. (If you installed the libraries globally on your system, you
    571 should be able to drop the hints in the `find_package()` calls.)
    572 
    573 Finally, you can add *Trompeloeil* to your project and then either (a) use CMake's
    574 `find_file()` to locate the header and add its path to
    575 `include_directories()`; or (b) use `add_subdirectory()` (one or two argument
    576 version) to add its path to your project.
    577 
    578 If you want to specify a version of *Trompeloeil*, drop the 'v' from the version
    579 name in `find_package`. E.g. `find_package( trompeloeil 39 EXACT )`.
    580 
    581 ### <A name="move_constructible"/> Q. Why are mock objects not move constructible?
    582 
    583 **A.** Because a move is potentially dangerous in non-obvious ways.
    584 If a mock object is moved, the actions associated with an expectation
    585 ([**`.WITH()`**](reference.md/#WITH),
    586  [**`.SIDE_EFFECT()`**](reference.md/#SIDE_EFFECT),
    587  [**`.RETURN()`**](reference.md/#RETURN),
    588  [**`.THROW()`**](reference.md/#THROW)) and their
    589  `LR_` versions, are *not* moved. If they refer to data members stored in a
    590  moved mock object, they will refer to dead data. This is an accepted cost
    591  in normal C++ code, but since the effect is hidden under the macros,
    592  it is better to play safe.
    593 
    594 With that said, you can explicitly make mock objects movable, if you want to.
    595 See: [**`trompeloeil_movable_mock`**](reference.md/#movable_mock).
    596 
    597 ### <A name="return_template"/> Q. Why can't I mock a function that returns a template?
    598 
    599 Like this:
    600 
    601 ```Cpp
    602 struct M
    603 {
    604   MAKE_MOCK2(make, std::pair<int,int>(int,int));
    605 };
    606 ```
    607 
    608 **A.** You can, but there is a limitation in the preprocessor, that makes it
    609 work poorly with templates. It sees the parameters to the
    610 [**`MAKE_MOCK2()`**](reference.md/#MAKE_MOCKn)
    611 macro above as `make`, `std::pair<int`, followed by `int>(int,int)`, which
    612 of course is nonsense and causes compilation errors.
    613 
    614 One easy way around this is to put the signature into parentheses:
    615 
    616 ```Cpp
    617 struct M
    618 {
    619   MAKE_MOCK2(make, (std::pair<int,int>(int,int)));
    620 };
    621 ```
    622 
    623 Or if you prefer the legacy way, create an alias:
    624 
    625 ```Cpp
    626 using pair_int_int = std::pair<int,int>;
    627 
    628 struct M
    629 {
    630   MAKE_MOCK2(make, pair_int_int(int,int));
    631 };
    632 ```
    633 
    634 These work around the preprocessor parameter problem.
    635 
    636 Another way, if you're mocking an interface, is to use
    637 [**`trompeloeil::mock_interface<T>`**](reference.md/#mock_interface)
    638 and [**`IMPLEMENT_MOCKn`**](reference.md/#IMPLEMENT_MOCKn). See
    639 [CookBook](CookBook.md/#creating_mock_classes) for an intro.
    640 
    641 ### <A name="mock_noexcept"/> Q. Can I mock a `noexcept` function?
    642 
    643 **A.** Yes, but with a caveat.
    644 
    645 The way to mock a
    646 [`noexcept`](https://en.cppreference.com/w/cpp/language/noexcept_spec)
    647 function is to add a `noexcept` specifier to
    648 [**`MAKE_MOCKn`**](reference.md/#MAKE_MOCKn) or
    649 [**`MAKE_CONST_MOCKn`**](reference.md/#MAKE_CONST_MOCKn).
    650 
    651 ```Cpp
    652 struct S
    653 {
    654     MAKE_MOCK1(func, void(int), noexcept);
    655     //                          ^^^^^^^^  noexcept function
    656 };
    657 ```
    658 
    659 The caveat is that the [violation handlers](CookBook.md/#unit_test_frameworks),
    660 and specifically the default one, reports violations by throwing an exception,
    661 which means that any call made in violation of the [expectation](
    662 reference.md/#expectation) for a
    663 `noexcept` function leads to program termination. How much information you can
    664 gain from such an event depends on the runtime system of your tools.
    665 
    666 ### <A name="saturated_expectation"/> Q. What does it mean that an expectation is "saturated"?
    667 
    668 If you see a violation report like this:
    669 
    670 ```text
    671 [file/line unavailable]:0: FATAL ERROR: No match for call of func with signature void(int) with.
    672   param  _1 == -3
    673 
    674 Matches saturated call requirement
    675   object.func(trompeloeil::_) at example.cpp:240
    676 ```
    677 
    678 What this means is that there is an expectation for the call, but that expectation is no
    679 longer allowed to be called, its maximum call count has been met.
    680 
    681 An example:
    682 
    683 ```Cpp
    684 test_func()
    685 {
    686     test_mock obj;
    687     REQUIRE_CALL(obj, func(trompeloeil::_))
    688       .TIMES(AT_MOST(2));
    689 
    690    exercise(obj); // calls obj.func. OK. Expectation is alive, no prior calls, this one is accepted
    691    exercise(obj); // calls obj.func. OK. Expectation is alive, one prior call, this one is accepted
    692    exercise(obj); // calls obj.func. Fail. Expectation is alive, two prior calls, this one saturated
    693 }
    694 ```