Skip to content

Latest commit

 

History

History
2381 lines (1804 loc) · 66.6 KB

reference.md

File metadata and controls

2381 lines (1804 loc) · 66.6 KB

Reference

A mock function is a member function that is mocked with MAKE_MOCKn(name, signature) or MAKE_CONST_MOCKn(name, signature).

Example:

class C
{
public:
  MAKE_MOCK1(func, void(int));
  MAKE_CONST_MOCK2(cfunc, int(std::string, int));
};

Above C is a type that has two mock functions void func(int) and int cfunc(std::string, int) const. With a mock object of type C it is possible to place expectations on the functions func(...) and cfunc(...).

A mock object is an object of a type that has mock functions.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(int));
};

C obj;

Above, obj is a mock object. It is possible to place expectations on mock functions for the object obj.

By default it is illegal to call mock functions. Expectations change that. Example:

class C
{
public:
  MAKE_MOCK1(func, void(int));
};

TEST(atest)
{
  C mock_obj;

  REQUIRE_CALL(mock_obj, func(3));

  tested_function(mock_obj);
}

Above mock_obj is a mock object with one mock function void func(int).

The line REQUIRE_CALL(mock_obj, func(3)) places an expectation that mock_obj.func(3) is called before the end of the scope. Unless tested_function(mock_obj) calls mock_obj.func(3) a violation is reported.

The ways to set expectations are:

Each NAMED variant returns an expectation as std::unique_ptr<trompeloeil::expectation> which can be saved in variables for storage in test fixtures or other programmatic lifetime control.

If expectations are not met by the time they go out or scope (or in case of the NAMED variants, when the object held by the std::unique_ptr<> is destroyed) a violation is reported.

By default there is no order imposed on expectations. One way to impose order is through their lifetimes. Another is by using IN_SEQUENCE(...).

If there are several expectations that match the same call, they are tried in the reverse order of creation, and the first found match is accepted. In other words, the last created matching expectation is the one used.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(int));
};

using trompeloeil::_;

TEST(atest)
{
  C mock_obj;

  ALLOW_CALL(mock_obj, func(_));
  FORBID_CALL(mock_obj, func(3));
  FORBID_CALL(mock_obj, func(4));

  tested_function(mock_obj);
}

Above, the first expectation ALLOW_CALL(...) matches everything using the wildcard trompeloeil::_, but the two FORBID_CALL(...) are created later and are thus matched first. This means that if tested_function(...) calls mock_obj.func(int) with 5, the two FORBID_CALL(...) do not match, but the ALLOW_CALL(...) does, so the call is allowed. A call with 3 or 4, results in a violation is report since a FORBID_CALL(...) is matched.

Each parameter in the parameter list of an expectation can be an exact value to match for equality (using operator==,) or a matcher. Matchers check a condition on the parameter value. Trompeloeil provides the matchers

You can also provide your own matchers.

Used in the parameter list of an expectation, trompeloeil::_ matches any value of any type.

Example:

class C
{
public:
  MAKE_MOCK1(func, int(int));
};

trompeloeil::_;

TEST(atest)
{
  C mock_obj;
  ALLOW_CALL(mock_obj, func(_))
    .RETURN(_1 + 1);

  test_function(&mock_obj);
}

Above, mock_obj.func() is allowed to be called with any value, and it will return 1 + the value provided.

If type information is needed, for example to disambiguate overloads, use ANY( type ).

Used in the parameter list of an expectation to match any value of a specified type. This can be used as an alternative to trompeloeil::_ when it is important to disambiguate between overloads.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(int));
  MAKE_MOCK2(func, void(std::string));
};

TEST(atest)
{
  C mock_obj;
  ALLOW_CALL(mock_obj, func(ANY(int)));

  test_function(&mock_obj);
}

Above, any call to mock_obj.func(int) is accepted, but calls to mock_obj.func(std::string) renders a violation report since there is no matching expectation.

Used in the parameter list of an expectation to match a value equal to the one provided. By default it matches any parameter type that supports operator==() with the value, but an explicit type can be specified if needed for disambiguation.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(int*));
  MAKE_MOCK1(func, void(const char*));
  MAKE_MOCK1(func, void(const std::string&));
};

using trompeloeil::eq;

TEST(atest)
{
  C mock_obj;
  ALLOW_CALL(mock_obj, func(*eq(3)));

  std::string expected = "foo";
  REQUIRE_CALL(mock_obj, func(eq<const char*>(expected)));

  test_function(&mock_obj);
}

Above, the first expectation matches only calls to mock_obj.func(int*) with a non-null pointer pointing to the value 3. Any call with a nullptr or a pointer pointing to a value other than 3 renders a violation report since no expectation matches.

The second expectation matches only calls to mock_obj.func(const char*), with a C-string "foo".

Used in the parameter list of an expectation to match a value not equal to the one provided. By default it matches any parameter type that supports operator!=() with the value, but an explicit type can be specified if needed for disambiguation.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(const char*));
  MAKE_MOCK1(func, void(const std::string&));
};

using trompeloeil::ne;

TEST(atest)
{
  C mock_obj;
  ALLOW_CALL(mock_obj, func(ne(nullptr)));
  REQUIRE_CALL(mock_obj, func(ne<std::string>("")));
  test_function(&mock_obj);
}

Above, the first expectation matches only calls to mock_obj.func(const char*) with non-null pointer. Any call with a nullptr renders a violation report since no expectation matches.

The second expectation matches only calls to mock_obj.func(const std::string&), with a non-empty string.

It is also possible to use *ne(val) to match a pointer to a non-equal value.

Used in the parameter list of an expectation to match a value greater than the one provided. By default it matches any parameter type that supports operator>() with the value, but an explicit type can be specified if needed for disambiguation.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(short));
  MAKE_MOCK1(func, void(int));
  MAKE_MOCK1(func, void(std::string));
};

using trompeloeil::gt;

TEST(atest)
{
  C mock_obj;
  ALLOW_CALL(mock_obj, func(gt<short>(0)));
  ALLOW_CALL(mock_obj, func(gt("foo")));

  test_function(&mock_obj);
}

Above, the first expectation matches only calls to mock_obj.func(short) with positive values. Any call with 0 or negative, and any calls to mock_obj.func(int) renders a violation report since no expectation matches.

The second expectation matches calls to mock_obj.func(std::string), since std::string is greater-than comparable with a string literal.

It is also possible to use *gt(val) to match a pointer to a greater-than value.

Used in the parameter list of an expectation to match a value greater than on equal to the one provided. By default it matches any parameter type that supports operator>=() with the value, but an explicit type can be specified if needed for disambiguation.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(int));
  MAKE_MOCK1(func, void(short));
  MAKE_MOCK1(func, void(std::string));
};

using trompeloeil::ge;

TEST(atest)
{
  C mock_obj;
  ALLOW_CALL(mock_obj, func(ge<short>(0)));
  REQUIRE_CALL(mock_obj, func(ge("foo")));

  test_function(&mock_obj);
}

Above, the first expectation matches only calls to mock_obj.func(short) with zero or positive values. Any call with a negative value renders a violation report since no expectation matches.

The second expectation matches only calls to mock_obj.func(std::string), since std::string is greater-than-or-equal-to comparable with string literal.

It is also possible to use *ge(val) to match a pointer to a greater-than or equal value.

Used in the parameter list of an expectation to match a value less than the one provided. By default it matches any parameter type that supports operator<() with the value, but an explicit type can be specified if needed for disambiguation.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(long));
  MAKE_MOCK1(func, void(int));
  MAKE_MOCK1(func, void(const std::string&));
};

using trompeloeil::lt;

TEST(atest)
{
  C mock_obj;
  ALLOW_CALL(mock_obj, func(lt<int>(0)));
  REQUIRE_CALL(mock_obj, func(lt("foo")));

  test_function(&mock_obj);
}

Above, the first expectation matches only calls to mock_obj.func(int) with negative values. Any call with 0 or positive renders a violation report since no expectation matches.

The second expectation matches calls to mock_obj.func(cost std::string&), since std::string is less-than comparable with string a literal.

It is also possible to use *lt(val) to match a pointer to a less-than value.

Used in the parameter list of an expectation to match a value less than or equal to the one provided. By default it matches any parameter type that supports operator<=() with the value, but an explicit type can be specified if needed for disambiguation.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(int));
  MAKE_MOCK1(func, void(short));
  MAKE_MOCK1(func, void(const char*));
};

using trompeloeil::le;
using std::string_literals;

TEST(atest)
{
  C mock_obj;
  ALLOW_CALL(mock_obj, func(le<short>(0)));
  REQUIRE_CALL(mock_obj, func(le("foo"s)));
  test_function(&mock_obj);
}

Above, first the expectation matches only calls to mock_obj.func(short) with zero or negative values. Any call with a positive value renders a violation report since no expectation matches.

The second expectation matches calls to mock_obj.func(const char*), since a c-string is less-than comparable with a std::string

It is also possible to use *le(val) to match a pointer to a less-than or equal value.

Used in the parameter list of an expectation to match a string with a regular expression.

re() exists in two flavours.

  • re( string, flags... ) which can match both C-strings (char*, const char*) as well as C++ std::string.
  • re<type>( string, flags... ) which can be used to disambiguate overloads.

For both versions, the string can be either std::string or a C-string.

flags... can be

  • empty
  • std::regex_constants::syntax_option_type
  • std::regex_constants::match_flag_type
  • std::regex_constants::syntax_option_type, std::regex_constants::match_flag_type

Regular expression matching is made with std::regex_search()

Example:

class C
{
public:
  MAKE_MOCK1(unique, void(std::string&));
  MAKE_MOCK1(overloaded, void(const char*));
  MAKE_MOCK1(overloaded, void(const std::string&));
};

using trompeloeil::re;

TEST(atest)
{
  C mock_obj;
  REQUIRE_CALL(mock_obj, unique(re("end$", std::regex_constants::icase)));
  REQUIRE_CALL(mock_obj, overloaded(re<const char*>("end", std::regex_constants::match_not_eol)));
  test_function(&mock_obj);
}

Above, test_function(&mock_obj) must call mock_obj.unique() with a string case insensitively matching the regular expression /end$/, and also call mock_obj.overloaded(const char*) with a regular expression matching the regular expression /end/.

It is also possible to use *re(string) to match a pointer to a string with a regular expression, or !re(string) to allow only strings that do not match a regular expression.

Used in the parameter list of an expectation together with a matcher, to match a value pointed to by a pointer. A nullptr value fails the matcher.

Example:

struct C {
  MAKE_MOCK1(func, void(int*));
};

using trompeloeil::eq; // matching equal values

TEST(atest)
{
  C mock_obj;
  REQUIRE_CALL(mock_obj, func(*eq(3)));
  test_function(&mock_obj);
}

Above, test_funciton(&mock_obj) must call mock_obj.func() with a pointer to the value 3.

Used in the parameter list of an expectation together with a matcher, to negate a matcher, i.e. to fail what the matcher allows, and to allow what the matcher fails.

Example:

struct C {
  MAKE_MOCK1(func, void(const std::string&));
};

using trompeloeil::re; // matching regular expressions

TEST(atest)
{
  C mock_obj;
  REQUIRE_CALL(mock_obj, func(!re("^foo")));
  test_function(&mock_obj);
}

Above, test_funciton(&mock_obj) must call mock_obj.func() with a string that does not begin with "foo".

Make an expectation that mock_object.func_name(parameter_list) may be called zero or more times until the end of the surrounding scope. parameter_list may contain exact values or matchers that describes matching calls.

This is the same as REQUIRE_CALL(...).TIMES( 0,infinity ).

Matches any number of times, but is not required to match. (actually the limit is 0..~0ULL, but that is for all practical purposes "infinity")

Example:

class C
{
public:
  MAKE_MOCK1(func, int(int));
};

trompeloeil::_;

TEST(atest)
{
  C mock_obj;
  ALLOW_CALL(mock_obj, func(_))
    .RETURN(_1 + 1);

  test_function(&mock_obj);
}

Above ALLOW_CALL(mock_obj, func(_)) places an expectation that mock_obj.func() may be called any number of times with any parameter value and will always return the parameter value + 1. test_function(...) is allowed to call mock_obj.func() any number of times (including no call at all).

The expectation is valid until the end of the scope, which in the example above is until after the return from test_function(...).

See also NAMED_ALLOW_CALL(...) which creates an expectation as a std::unique_ptr<trompeloeil::expectation> which can be stored in test fixtures or otherwise have its lifetime programmatically controlled.

A matcher for use in the parameter list of an expectation to disambiguate overloaded functions on type when the exact value is unimportant. See the matcher ANY( type ) above.

Used in TIMES(...) to set the range number..infinity. number must be constexpr.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(int));
};

using trompeloeil::_;

TEST(atest)
{
  C mock_obj;
  REQUIRE_CALL(mock_obj, func(_))
    .TIMES(AT_LEAST(3));
  tested_function(&mock_obj);
}

Above, the line TIMES(AT_LEAST(3)) modifies the expectation such that mock_obj.func() must be called 3 times or more, before the end of the scope, or a violation is reported.

In reality the upper limit is ~0ULL, but that is for all practical purposes "infinity".

Used in TIMES(...) to set the range 0..number. number must be constexpr.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(int));
};

using trompeloeil::_;

TEST(atest)
{
  C mock_obj;
  REQUIRE_CALL(mock_obj, func(_))
    .TIMES(AT_MOST(3));
  tested_function(&mock_obj);
}

Above, the line TIMES(AT_MOST(3)) modifies the expectation such that mock_obj.func() must be called 3 times or less (including no call at all) before the end of the scope, or a violation is reported.

Make an expectation that mock_object.func_name(parameter_list) must not be called until the end of the scope. parameter_list may contain exact values or matchers that describes matching calls.

This is the same as REQUIRE_CALL(...).TIMES( 0 ), making any matching call an error. This is often done in a narrow scope where the wider scope would allow the call. LR_RETURN(...), RETURN(...), LR_THROW(...) and THROW(...) are illegal in a FORBID_CALL(...).

Example:

class C
{
public:
  MAKE_MOCK1(func, void(int));
};

using trompeloeil::_;

TEST(atest)
{
  C mock_obj;
  ALLOW_CALL(mock_obj, func(_));

  tested_function(1, &mock_obj);

  {
    FORBID_CALL(mock_obj, func(2));

    tested_function(2, &mock_obj);
  }

  tested_function(3, &mock_obj);
}

Above, the mock function C::func(int) may be called with any value for mock_obj, except in the scope of the tested_function(2, &mock_obj), where mock_obj.func(2) would lead to a violation being reported. At tested_function(3, &mock_obj) any value is allowed again.

See also NAMED_FORBID_CALL(...) which creates an expectation as a std::unique_ptr<trompeloeil::expectation> which can be stored in test fixtures or otherwise have its lifetime programmatically controlled.

Make a const mock function implementation of the virtual function named func_name from the inherited interface. This macro is only usable with virtual non-final functions, and only when used with mock_interface<T>, where T is the interface.

Example:

class I
{
public:
  virtual ~I() = default;
  virtual int func(int, const std::vector<int>&)) const = 0;
};

class C : public trompeloeil::mock_interface<I>
{
public:
  IMPLEMENT_CONST_MOCK2(func);
};

Above, class C will effectively become:

class C : public trompeloeil::mock_interface<I>
{
public:
  int func(int, const std::vector<int>&) const override;
};

It is not possible to mock operators, constructors or the destructor, but you can call mock functions from those.

NOTE! IMPLEMENT_CONST_MOCKn(...) cannot handle overloaded functions.

See also IMPLEMENT_MOCKn(...) for non-const member functions.

See also MAKE_MOCKn(...) and MAKE_CONST_MOCKn(...) for making mock implementations of any member functions.

Make a non-const mock function implementation of the virtual function named func_name from the inherited interface. This macro is only usable with virtual non-final functions, and only when used with mock_interface<T>, where T is the interface.

Example:

class I
{
public:
  virtual ~I() = default;
  virtual int func(int, const std::vector<int>&)) = 0;
};

class C : public trompeloeil::mock_interface<I>
{
public:
  IMPLEMENT_MOCK2(func1);
};

Above, class C will effectively become:

class C : public trompeloeil::mock_interface<I>
{
public:
  int func(int, const std::vector<int>&) override;
};

It is not possible to mock operators, constructors or the destructor, but you can call mock functions from those.

NOTE! IMPLEMENT_MOCKn(...) cannot handle overloaded functions.

See also IMPLEMENT_CONST_MOCKn(...) for const member functions.

See also MAKE_CONST_MOCKn(...) for const member functions.

Where seq... is one or more instances of trompeloeil::sequence. Impose an order in which expectations and destruction of deathwatched_type objects must match. Several sequences can be parallel and interleaved. A sequence for an expectation is no longer monitored once the lower limit from TIMES(...) is reached.

Example:

class Mock
{
public:
  MAKE_MOCK1(func, void(int));
  MAKE_MOCK1(func, void(const std::string&));
};

class ephemeral
{
public:
  virtual ~ephemeral() {};
};

TEST(atest)
{
  Mock m[2];
  auto e = new trompeloeil::deathwatched<ephemeral>;

  trompeloeil::sequence seq1, seq2;

  REQUIRE_CALL(m[0], func(ANY(int))
    .IN_SEQUENCE(seq1, seq2);

  REQUIRE_CALL(m[0], func(ANY(const std::string&))
    .IN_SEQUENCE(seq1);

  REQUIRE_CALL(m[1], func(ANY(const std::string&))
    .IN_SEQUENCE(seq2);

  REQUIRE_CALL(m[1], func(ANY(int))
    .IN_SEQUENCE(seq1, seq2);

  REQUIRE_DESTRUCTION(*e)
    .IN_SEQUENCE(seq1, seq2);

  tested_func(&m[0], &m[1], e);
}

All sequence objects are listed in the first REQUIRE_CALL(...), thus it must be the first expectation matched. Likewise all sequences are listed in the last REQUIRE_CALL(...), so it must be last expectaiton matched. The intermediate expectations has one sequence object each, thus they have no matching order imposed between them. Last of all is the REQUIRE_DESTRUCTION(...), which also lists all sequence objects and must happen after all other expectations are fulfilled.

The above allows the following two sequences only.

  • m[0].func(int) -> m[0].func(string) -> m[1].func(string) -> m[1].func(int) -> delete e
  • m[0].func(int) -> m[1].func(string) -> m[0].func(string) -> m[1].func(int) -> delete e

Any other sequence of calls renders a violation report.

Used in expectations to set the return value after having evaluated every SIDE_EFFECT(...) and LR_SIDE_EFFECT(...). For void functions LR_RETURN(...) is illegal. For non-void functions exactly one of RETURN(...), LR_RETURN(...), LR_THROW(...) or THROW(...) is required. expr may refer to parameters in the call with their positional names _1, _2, etc. This code may alter out-parameters.

If you need to return an lvalue-reference, to a variable, use std::ref(value) or std::cref(value) for it, or just enclose the value in an extra parenthesis, like this .LR_RETURN((value)).

NOTE! Any named local objects named in expr are captured by reference so lifetime management is important.

Example:

class C
{
public:
  MAKE_MOCK1(func, int&(unsigned));
};

TEST(atest)
{
  C mock_obj;

  int rv = 3;
  ALLOW_CALL(mock_obj, func(0))
    .LR_RETURN(std::ref(rv)); // reference to captured local variable

  rv = 4;
  test_func(&mock_obj);
}

Above, the LR_RETURN(...) clause tells matching calls of mock_obj.func(...) to return a reference to the local variable rv. Since LR_RETURN(...) accesses local variables by reference, the value of the returned reference will be 4 if called from within test_func(...).

See also RETURN(...) which accesses copies of local variables.

Used in expectations to cause side effects for matching calls. expr is only evaluated when all WITH(...) and LR_WITH(...) clauses are matched. expr may refer to parameters in the call with their positional names _1, _2, etc. This code may alter out-parameters. Several LR_SIDE_EFFECT(...) and SIDE_EFFECT(...) clauses can be added to a single expectation, and they are evaluated in order.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(unsigned));
};

TEST(atest)
{
  C mock_obj;
  unsigned sum = 0;
  ALLOW_CALL(mock_obj, func(ANY(unsigned))
    .LR_SIDE_EFFECT(sum += _1);

  tested_func(&mock_obj);

  std::cout << "parameter sum=" << sum << "\n";
}

Above, tested_func(&mock_obj) is allowed to call C::func(int) any number of times on mock_obj. Each time a side effect is that the local variable sum gets the parameter value added to it. Since LR_SIDE_EFFECT(...) refers to sum by reference, it is the actual local variable that is changed is every call.

See also SIDE_EFFECT(...) which accesses copies of local objects.

Used in expectations to throw after having evaluated every SIDE_EFFECT(...) and LR_SIDE_EFFECT(...) for a matching call. expr may refer to parameters in the call with their positional names _1, _2, etc. This code may alter out-parameters. It is not legal to combine LR_THROW(...) with any of THROW(...), LR_RETURN(...) or RETURN(...). Named local objects are accessed by reference so lifetime management is important.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(unsigned));
};

TEST(atest)
{
  C mock_obj;
  const char* what="";

  ALLOW_CALL(mock_obj, func(3))
    .LR_THROW(std::invalid_argument(what));

  what = "nonsense";
  tested_func(&mock_obj);
}

Above, LR_THROW(std::invalid_argument(what)) will refer to the C-string what with the value it has at the time of a call to mock_obj.func(3), i.e. "nonsense" if tested_func() does the call.

See also THROW(...) which accesses copies of local objects.

Used with expectations to add further conditions for a matching call. Typically used when matchers are used for the parameters, and often when the condition requires several parameter values together. expr can refer to parameters in the call with their positional names _1, _2, etc. Even if the function signature has parameters as non-const references, they are immutable in this context. Several LR_WITH(...) and WITH(...) clauses can be added to a single expectation and they are tried in the order they are added until one has failed, or they all have passed.

Named local objects are accessed by reference so lifetime management is important.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(const char*));
};

using trompeloeil::_;

TEST(atest)
{
  C mock_obj;

  const char buff[] = "string";

  REQUIRE_CALL(mock_obj, func(_))
    .LR_WITH(_1 == buff);

  tested_func(buff, &mock_obj);
}

Above, LR_WITH(_1 == buff) checks the condition that the const char* parameter is the same pointer value as the address to the local array buff.

NOTE! It is legal, but a very bad idea, to modify global/static objects in LR_WITH(...). If several expectations could match and are disambiguated by LR_WITH(...) and WITH(...) the global/static objects will be modified also by those expectations that do not match.

See also WITH(...) which accesses copies of local objects.

Make a const mock function named func_name. It is a good idea for this to implement a pure virtual function from an interface, but it is not a requirement. n is the number of parameters in signature. specifiers is an optional list which may include attributes or specifiers like override.

Example:

class I
{
public:
  virtual ~I() = default;
  virtual int func1(int, const std::vector<int>&)) const = 0;
};

class C
{
public:
  MAKE_CONST_MOCK2(func1, int(int, const std::vector<int>&), override);
  MAKE_CONST_MOCK1(func2, int(std::string));
};

Above, class C will effectively become:

class C : public I
{
public:
  int func1(int, const std::vector<int>&) const override;
  int func2(std::string) const;
};

It is not possible to mock operators, constructors or the destructor, but you can call mock functions from those.

See also MAKE_MOCKn(...) for non-const member functions.

Make a non-const mock function named func_name. It is a good idea for this to implement a pure virtual function from an interface, but it is not a requirement. n is the number of parameters in signature. specifiers is an optional list which may include attributes or specifiers like override.

Example:

class I
{
public:
  virtual ~I() = default;
  virtual int func1(int, const std::vector<int>&)) = 0;
};

class C : public I
{
public:
  MAKE_MOCK2(func1, int(int, const std::vector<int>&), override);
  MAKE_MOCK1(func2, int(std::string));
};

Above, class C will effectively become:

class C : public I
{
public:
  int func1(int, const std::vector<int>&) override;
  int func2(std::string);
};

It is not possible to mock operators, constructors or the destructor, but you can call mock functions from those.

See also MAKE_CONST_MOCKn(...) for const member functions.

Make a std::unique_ptr<trompeloeil::expectation> allowing mock_object.func_name(parameter_list) to be called zero or more times until the expectation object is destroyed. parameter_list may contain exact values or matchers that describes matching calls.

This is the same as NAMED_REQUIRE_CALL(...).TIMES( 0,infinity ).

Matches any number of times, but is not required to match. (Actually the limit is 0..~0ULL, but that is for all practical purposes "infinity".)

NOTE! Any named objects referenced in attached LR_WITH(...), LR_SIDE_EFFECT(...), LR_RETURN(...) and LR_THROW(...) are captured by reference so lifetime management is important.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(int));
};

using trompeloeil::gt;
using trompeloeil::lt;
using expectation = std::unique_ptr<trompeloeil::expectation>;

TEST(atest)
{
  C mock_obj;

  expectation x1 = NAMED_ALLOW_CALL(mock_obj, func(gt(0));

  test_function(0, &mock_obj);

  expectation x2 = NAMED_ALLOW_CALL(mock_obj, func(lt(0));

  test_function(1, &mock_obj);

  x1.reset(); // no longer allow calls with positive values

  test_function(2, &mock_obj);
}

Above each NAMED_ALLOW_CALL(mock_obj, func(...)) creates an expectation that mock_obj.func() may be called any number of times. Each expectation is valid for the lifetime of the expectation object. In the example above, this means that x1 is valid for the first two calls to test_function(...), while x2 is valid for the last two calls to test_function(...).

See also ALLOW_CALL(...) which creates an expectation that is valid until the end of the surrounding scope.

Make a std::unique_ptr<trompeloeil::expectation> disallowing calls to mock_object.func_name(parameter_list) until the expectation object is destroyed. parameter_list may contain exact values or matchers that describes matching calls.

This is the same as NAMED_REQUIRE_CALL(...).TIMES( 0 ), making any matching call an error. This is typically done when a wider scope would allow the call. RETURN(...), LR_RETURN(...), LR_THROW(...) and THROW(...) are illegal in a NAMED_FORBID_CALL(...).

NOTE! Any named objects referenced in attached LR_WITH(...) are captured by reference so lifetime management is important.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(int));
}

using trompeloeil::_;
using trompeloeil::gt;
using trompeloeil::lt;

using expectation = std::unique_ptr<trompeloeil::expectation>;

TEST(atest)
{
  C mock_obj;

  ALLOW_CALL(mock_obj, func(_));

  expectation x1 = NAMED_FORBID_CALL(mock_obj, func(gt(0));

  test_function(0, &mock_obj);

  expectation x2 = NAMED_FORBID_CALL(mock_obj, func(lt(0));

  test_function(1, &mock_obj);

  x1.reset(); // allow calls with positive values again

  test_function(2, &mock_obj);
}

Above, calls to mock_obj.func() are generally allowed throughout the test. However, x1 imposes a restriction that calls with positive values are illegal, and that restriction is in place for the first two calls to test_function(...). x2 imposes a restrictions that calls with negative values are illegal, and that restriction is in place for the last two calls to test_function(...).

See also FORBID_CALL(...) which creates an expectation that is valid until the end of the surrounding scope.

Make a std::unique_ptr<trompeloeil::expectation> requiring that mock_obj.func_name(parameter_list) is called exactly once before the expectation object is destroyed. parameter_list may contain exact values or matchers that describes matching calls.

The number of matches required before the expectation object is destroyed can be changed with an optional TIMES(...) clause.

NOTE! Any named objects referenced in attached LR_WITH(...), LR_SIDE_EFFECT(...), LR_RETURN(...) and LR_THROW(...) are captured by reference so lifetime management is important.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(int));
}

using trompeloeil::gt;
using trompeloeil::lt;

using expectation = std::unique_ptr<trompeloeil::expectation>;

TEST(atest)
{
  C mock_obj;

  expectation x1 = NAMED_REQUIRE_CALL(mock_obj, func(gt(0));

  test_function(0, &mock_obj);

  expectation x2 = NAMED_REQUIRE_CALL(mock_obj, func(lt(0));

  test_function(1, &mock_obj);

  x1.reset(); // The call with positive number must be done here.

  test_function(2, &mock_obj);
}

Above, the first two calls to test_function(...) must together call mock_obj.func(...) exactly once with a positive value, and the last two calls to test_function(...) must together call mock_obj.func(...) exactly once with a negative number.

See also REQUIRE_CALL(...) which creates an expectation that is valid until the end of the surrounding scope.

Create a std::unique_ptr<trompeloeil::expectation> object which reports a violation if the deathwatched_type mock object is not destroyed by the time the expectation is destroyed.

Example:

class C
{
public:
  virtual ~C() = default; // must be virtual for deathwatched
  MAKE_MOCK1(func, void(int));
}

using monitor = std::unique_ptr<trompeloeil::expectation>;
using trompeloeil::deathwatched;

TEST(atest)
{
  C* p = new deathwatched<C>();

  test_function(0, p); // must not destroy *p

  monitor m = NAMED_REQUIRE_DESTRUCTION(*p);

  test_function(1, p);

  m.reset(); // *p must have been destroyed here
}

Above, p points to a deathwatched mock object, meaning that a violation is reported if *p is destroyed without having a destruction requirement.

The monitor m is a requirement that *p is destroyed before the lifetime_monitor (subtype of expectation) held by m is destroyed.

It is thus a violation if the first call to test_function(...) destroys *p, and another violation if the second call to test_function(...) does not destroy *p

See also REQUIRE_DESTRUCTION(...) which places a requirement that the deathwatched mock object is destroyed before the end of the scope.

Make an expectation requiring that mock_obj.func_name(parameter_list) is called exactly once before the end of the scope. parameter_list may contain exact values or matchers that describes matching parameter values for the expectation.

The number of matches required before the expectation object is destroyed can be changed with an optional TIMES(...) clause.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(int));
}

using trompeloeil::gt;
using trompeloeil::lt;

TEST(atest)
{
  C mock_obj;
  {
    REQUIRE_CALL(mock_obj, func(gt(0));

    test_function(0, &mock_obj);
    // end of scope, requirement must be fulfilled here
  }
  {
    REQUIRE_CALL(mock_obj, func(lt(0));

    test_function(1, &mock_obj);
    // end of scope, requirement must be fulfilled here
  }
}

Above, the first call to test_function(...) must call mock_obj.func(...) exactly once with a positive value, and the second call to test_function(...) must call mock_obj.func(...) exactly once with a negative number.

See also NAMED_REQUIRE_CALL(...) which creates an expectation that is held by a std::unique_ptr<trompeloeil::expectation> which can be stored in test fixtures.

Create an anonymous lifetime_monitor which reports a violation if the deathwatched mock object is not destroyed by the end of the scope.

Example:

class C
{
public:
  virtual ~C() = default; // must be virtual for deathwatched
  MAKE_MOCK1(func, void(int));
}

using trompeloeil::deathwatched;

TEST(atest)
{
  C* p = new deathwatched<C>();

  test_function(0, p); // must not destroy *p

  {
    REQUIRE_DESTRUCTION(*p);

    test_function(1, p);
    // end of scope, *p must have been destroyed here
  }
}

Above, p points to a deathwatched mock object, meaning that a violation is reported if *p is destroyed without having a destruction requirement.

REQUIRE_DESTRUCTION(...) in the local scope puts a requirement on *p that it must be destroyed by the end of the scope.

It is thus a violation if the first call to test_function(...) destroys *p, and another violation if the second call to test_function(...) does not destroy *p.

See also NAMED_REQUIRE_DESTRUCTION(...) which creates the requirement that the deathwatched mock object is destroyed as a std::unique_ptr<trompeloeil::lifetime_monitor> which can be stored in test fixtures.

Used in expectations to set the return value after having evaluated every SIDE_EFFECT(...) and LR_SIDE_EFFECT(...). For void functions RETURN(...) is illegal. For non-void functions exactly one of LR_RETURN(...), RETURN(...), LR_THROW(...) or THROW(...) is required. expr may refer to parameters in the call with their positional names _1, _2, etc. This code may alter out-parameters.

Named local objects accessed here refers to a immutable copies.

Example:

class C
{
public:
  MAKE_MOCK1(func, int&(unsigned));
};

using trompeloeil::_;

std::vector<int> values{3,2,1,0};

TEST(atest)
{
  C mock_obj;

  int offset = 1;
  ALLOW_CALL(mock_obj, func(_))
    .WITH(_1 + offset < values.size())
    .RETURN(values[_1 + offset]);

  offset = 2;
  test_func(&mock_obj);
}

Above, the RETURN(...) clause tells matching calls of mock_obj.func(...) to return a reference to an element in the global std::vector<int> values. Since RETURN(...) accesses copies of local variables, the value of offset is 1 in the index calculation if called from within test_func(...).

NOTE! It is illegal to return a reference to a captured local variable.

See also LR_RETURN(...) which accesses local variables by reference.

Used in expectations to cause side effects for matching calls. expr is only evaluated when all WITH(...) and LR_WITH(...) clauses are matched. expr may refer to parameters in the call with their positional names _1, _2, etc. This code may alter out-parameters. Several SIDE_EFFECT(...) and LR_SIDE_EFFECT(...) clauses can be added to a single expectation, and they are evaluated in order.

Named local objects accessed here refers to immutable copies.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(unsigned));
};

unsigned sum = 0;

TEST(atest)
{
  C mock_obj;
  unsigned offset = 0;
  ALLOW_CALL(mock_obj, func(ANY(unsigned))
    .SIDE_EFFECT(sum += offset + _1);

  offset = 2;
  tested_func(&mock_obj);

  std::cout << "offset corrected parameter sum=" << sum << "\n";
}

Above, tested_func(...) is allowed to call mock_obj.func() any number of times. Each time a side effect is that the global variable sum gets the parameter value added to it adjusted for offset. Since SIDE_EFFECT(...) refers to a copy of offset, the value of offset is 0 in any matching calls from within tested_func(...)

See also LR_SIDE_EFFECT(...) which accesses local objects by reference.

Used in expectations to throw after having evaluated every SIDE_EFFECT(...) and LR_SIDE_EFFECT(...) for a matching call. expr may refer to parameters in the call with their positional names _1, _2, etc. This code may alter out-parameters. It is not legal to combine THROW(...) with any of LR_THROW(...), LR_RETURN(...) or RETURN(...).

Named local objects here refers to immutable copies.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(unsigned));
};

TEST(atest)
{
  C mock_obj;
  std::string what="<unknown>";

  ALLOW_CALL(mock_obj, func(3))
    .THROW(std::invalid_argument(what));

  what = "";
  tested_func(&mock_obj);
}

Above, THROW(...) will refer to a copy of the string what with the value "<unknown>" if a matching call is made from within tested_func(...)

See also LR_THROW(...) which accesses copies of local objects.

Used in REQUIRE_CALL(...) and NAMED_REQUIRE_CALL(...) to set the limits on the number of matching calls required.

limits may be a single number, in which case it is the exact number of matching calls required.

limits may also be two numbers, describing a range min-inclusive, max-inclusive.

If the minimum number of matching calls in not met before the end of the lifetime of the expectation, a violation is reported.

If the maximum number of matching calls is exceeded, a violation is reported.

limits must be constexpr.

TIMES(...) may only be used once for each REQUIRE_CALL(..) or NAMED_REQUIRE_CALL(...).

Example:

class C
{
public:
  MAKE_MOCK1(func, void(unsigned));
};

using trompeloeil::_;

TEST(atest)
{
  C mock_obj;

  REQUIRE_CALL(mock_obj, func(_))
    .TIMES(2, 5);

  tested_func(&mock_obj);

Above, tested_func(...) is expected to call mock_obj.func() at least two times, and no more than 5 times.

See also the helpers AT_LEAST(...) and AT_MOST(...).

Used with expectations to add further conditions for a matching call. Typically used when matchers are used for the parameters, and often when the condition requires several parameter values together. expr can refer to parameters in the call with their positional names _1, _2, etc. Even if the function signature has parameters as non-const references, they are immutable in this context. Several WITH(...) and LR_WITH(...) clauses can be added to a single expectation and they are tried in the order until one has failed, or they all have passed.

Named local objects here refers to immutable copies.

Example:

class C
{
public:
  MAKE_MOCK1(func, void(const char*, size_t));
};

using trompeloeil::_;

TEST(atest)
{
  C mock_obj;

  std::string str = "string";

  REQUIRE_CALL(mock_obj, func(_,_))
    .WITH(std::string(_1, _2) == str);

  str = ""; // does not alter the copy in the expectation above.

  tested_func(buff, &mock_obj);
}

Above, WITH(std::string(_1, _2) == str) checks the condition that the string constructed from the parameters is equal to a copy of the local variable str. To pass the test, tested_func(...) must in other words call mock_obj.func() with string "string".

NOTE! It is legal, but a very bad idea, to modify global/static objects in WITH(...). If several expectations could match and are disambiguated by LR_WITH(...) and WITH(...) the global/static objects will be modified also by those expectations that do not match.

See also LR_WITH(...) which accesses local objects by reference.

Template used when it is necessary to control the life time of a mock object. The macros REQUIRE_DESTRUCTION(...) and NAMED_REQUIRE_DESTRUCTION(...) operates on instances of trompeloeil::deathwatched<T>.

Example:

class Mock
{
public:
  virtual ~Mock() = default; // virtual destructor needed for deathwatched<>
  MAKE_MOCK1(func, void(int));
};

using trompeloeil::_;

void test_func()
{
  auto p = new trompeloeil::deathwatched<Mock>();
  ALLOW_CALL(*p, func(_));
  func1(p);
  {
    FORBID_CALL(*p, func(_));
    REQUIRE_DESTRUCTION(*p);
    func2(p);
  }
}

Above, func1(p) must not destroy p, or a violation is reported, and func2(p) may not call the mock function on p, but is required to destroy the mock objeck, or a violation will be reported.

trompeloeil::deathwatched<T> inherits from T, and the constructor accepts any parameters and perfectly forwards them to the constructor of T. The mock type T must have a virtual destructor.

Base class for all expectations. The macros NAMED_ALLOW_CALL(...), NAMED_FORBID_CALL(...) and NAMED_REQUIRE_CALL(...) results in a std::unique_ptr<trompeloeil::expectation> which you can hold in a variable.

The exception type used by default to report violations.

class expectation_violation : public std::logic_error
{
public:
  using std::logic_error::logic_error;
};

The what() string contains the violation report message.

The macro NAMED_REQUIRE_DESTRUCTION(...) results in a std::unique_ptr<trompeloeil::lifetime_monitor> which you can hold in a varaible. trompeloeil::lifetime_monitor inherits from trompeloeil::expectation.

Example:

class Mock
{
public:
  virtual ~Mock() = default; // virtual destructor needed for deathwatched<>
  MAKE_MOCK1(func, void(int));
};

using trompeloeil::_;
using monitor = std::unique_ptr<trompeloeil::lifetime_monitor>;

void test_func()
{
  auto p = new trompeloeil::deathwatched<Mock>();
  ALLOW_CALL(*p, func(_));
  func1(p);
  {
    FORBID_CALL(*p, func(_));
    monitor m = NAMED_REQUIRE_DESTRUCTION(*p);
    std::unique_ptr<trompeloeil::expectation> e = std::move(m);
    func2(p);
    e.reset();
  }
}

trompeloeil::matcher is the base class for all matchers. It does not do anything and is solely used in internal SFINAE constructions and tag dispatch

Use it, or trompeloeil::typed_matcher<T>, as the base class when writing custom matchers.

trompeloeil::mock_interface<T> is a template useful when creating a mock from an existing interface (i.e. a struct or class with virtual functions that you want to mock).

It enables use of the IMPLEMENT_MOCKn(...) and IMPLEMENT_CONST_MOCKn(...) macros. The MAKE_MOCKn(...) and MAKE_CONST_MOCKn(...) macros can also be used.

The interface type T must not be final.

Example:

class interface
{
public:
  virtual ~interface() = default;
  virtual void func(int) = 0;
};

class mock : trompeloeil::mock_interface<interface>
{
public:
  IMPLEMENT_MOCK1(func); // implements pure virtual interface::func(int);
};

void tested_func(interface& i);

void test()
{
  mock m;
  REQUIRE_CALL(m, func(3));
  tested_func(m);
}

NOTE! mock_interface<T> cannot be used to inherit multiple interfaces.

Type of object used for fine-tuned control of sequencing of matched expectations.

Example:

class FileOps
{
public:
  using handle = int;
  MAKE_MOCK1(open, handle(const std::string&));
  MAKE_MOCK3(write, size_t(handle, const char*, size_t));
  MAKE_MOCK1(close, void(handle));
};

using trompeloeil::ne;

void test()
{
  FileOps ops;

  auto seq = trompeloeil::sequence; // sequence object

  int handle = 4711;

  REQUIRE_CALL(ops, open("name"))
    .RETURN(handle)
    .IN_SEQUENCE(seq);

  REQUIRE_CALL(ops, write(handle, ne(nullptr), ne(0)))
    .RETURN(0)                                         // indicate failure
    .IN_SEQUENCE(seq);

  REQUIRE_CALL(ops, write(handle, ne(nullptr), ne(0)))
    .RETURN(_3)                                        // successful retry
    .IN_SEQUENCE(seq);

  REQUIRE_CALL(ops, close(handle))
    .IN_SEQUENCE(seq);

  test_writes(&ops);
}

Sequence objects are movable but not copyable.

NOTE! The .IN_SEQUENCE(...) macro accepts many sequence objects.

Type used in violation reports to dictate what actions are allowed by the report handler.

namespace trompeloeil {
  enum class severity { fatal, nonfatal };
}

A value of trompeloeil::severity::fatal dictates that the report handler must not return. It may throw or end the program execution.

A value of trompeloeil::severity::nonfatal dictates that the report handler is called from stack rollback and must not throw, lest std::terminate is called.

An instance of trompeloeil::stream_tracer prints information about matched calls to the output stream it refers to. stream_tracer inherits from trompeloeil::tracer.

namespace trompeloeil {
class stream_tracer : public ::trompeloeil::tracer
{
public:
  stream_tracer(std::ostream& stream);
  void trace(char const* file, unsigned long line, std::string const& call) override;
};
}

See "Using trompeloeil::stream_tracer" in the Cook Book.

Base class for tracers. Inherit from it when writing custom tracers.

namespace trompeloeil {
class tracer
{
public:
  virtual void trace(char const* file, unsigned long line, std::string const& call) = 0;
protected:
   tracer();
   tracer(tracer const&) = delete;
   virtual ~tracer();
   ...
};
}

See "Writing custom tracers" in the Cook Book for an example.

Convenience class available when writing custom matchers for a specific type. It inherits from trompeloeil::matcher.

See "Writing custom matchers" in the Cook Book for examples.

Query an expectation object if it is satisfied, i.e. if it will not report a missing call if it is destroyed. If .TIMES() is used, this is true if the minimum number of calls has been reached.

test(...)
{
  ...
  auto e = NAMED_REQUIRE_CALL(mock_obj, func())
             .TIMES(2,5);
  assert(!e->is_satisfied()); // no calls made yet.
  mock_obj.func();
  assert(!e->is_satisfied()); // Only one call made, min is 2.
  mock_obj.func();
  assert(e->is_satisfied()); // now 2 calls are made, so it's satisfied
  mock_obj.func();
  assert(e->is_satisfied()); // 3 calls are made, it's still satisfied
}

Query an expectation object if it is saturated, i.e. if another call will report an unexpected call. If .TIMES() is used, this is true if the maximum number of calls has been reached.

  ...
  auto e = NAMED_REQUIRE_CALL(mock_obj, func())
             .TIMES(2,4);
  assert(!e->is_saturated()); // no calls made yet.
  mock_obj.func();
  assert(!e->is_saturated()); // Only one call made, max is 4.
  mock_obj.func();
  assert(!e->is_saturated()); // now 2 calls are made, still not saturated
  mock_obj.func();
  assert(!e->is_saturated()); // 3 calls, one more to go.
  mock_obj.func();
  assert(e->is_saturated());  // 4 calls, the expectation is now saturated

  /* mock_obj.func();*/ // would cause "unexpected call" error.

Get the global recursive_mutex used by Trompeloeil. The mutex is held until the end of the scope.

By default print() uses os << t, provided the type T can be inserted into an ostream. If not, it gives a hex-dump of the bytes occupied by the object.

You can write specializations of trompeloeil::print(std::ostream& os, T const& t) for your own types T. See example in the Cook Book.

Null check that works for all types. If T is not comparable with nullptr the value is false. This is mostly used when writing duck typed matchers.

template <typename Type, typename Predicate, typename Printer, typename ... T>
auto make_matcher(Predicate predicate /* bool (Type& value, T const& ...) */,
                  Printer printer     /* void (std::ostream&, T const& ...) */,
                  T&& ... stored_values);

If Type is trompeloeil::wildcard a duck typed matcher is created, otherwise a matcher for the specified type Type is created.

T&&... is any number of values you want stored in the matcher.

predicate is a callable object, typically a lambda, that accepts the value to check for, and each of the stored values T&&... in order as const&. When Type is trompeloeil::wildcard, the first parameter must be of auto type. The return value must be convertible to bool.

printer is a callable object, typically a lambda, that accepts an ostream& and the stored values T&&... in order as const&.

Examples are found in the Cook Book under Writing custom matchers

This function is used to adapt Trompeloeil to your unit test framework of choice.

The default reporter throws trompeloeil::expectation_violation for all reports, with the violation message in the what() string.

If this is not suitable, you can change the report mechanism by calling trompeloeil::set_reporter(...)

trompeloeil::set_reporter(std::function<void(trompeloeil::severity,
                                             char const *file,
                                             unsigned long line,
                                             const std::string& msg)>)

See trompeloeil::severity for the rules that it dictates.

The Cook Book lists adapter code for a number of popular unit test frame works.

Member function of sequence object, used to query if the sequence it describes is completed or not.

Example:

void test()
{
  auto seq = trompeloeil::sequence;
  mock_type mock;
  REQUIRE_CALL(mock, func1())
    .IN_SEQUENCE(seq);
  REQUIRE_CALL(mock, func2())
    .TIMES(100)
    .IN_SEQUENCE(seq);
  assert(!seq.is_completed()); // no calls yet
  mock.func1();
  assert(!seq.is_completed()); // only first call, one remaining
  mock.func2();
  assert(seq.is_completed());  // now sequence is completed
}

By adding a static constexpr bool member trompeloeil_movable_mock with the value true to your mock struct/class, you make it move constructible. Note that when a mock object is moved, any current expectations will be taken over by the newly constructed mock object, but note also that if the implicitly created lambdas associated with .WITH(), .SIDE_EFFECT(), .RETURN() and .THROW() and their **LR_** counter parts, refers to member variables in the mock objects, they will continue to refer the old moved from object.

class immobile
{
public:
  MAKE_MOCK1(func, void(int));
};

class movable
{
public:
  int i = 0;
  
  static constexpr bool trompeloeil_movable_mock = true;
  // allow move construction
  
  MAKE_MOCK1(func, void(int));
};

template <typename T>
T transfer(T t)
{
  return t;
}

test(...)
{
  auto m = transfer(immobile{}); // compilation error
  ...
}
test(...)
{
  movable m;
  auto e = NAMED_REQUIRE_CALL(m, func(3));
  auto mm = transfer(std::move(m));
   // A call to mm.func() now satisfies e
  ...
}
test(...)
{
  movable m{3};
  auto e = NAMED_REQUIRE_CALL(m, func(_))
    .LR_WITH(_1 == m.i);
  auto mm = transfer(std::move(m)); // Danger! e still refers to m.i.
  ...
}

Also, keep in mind the lifetime of expectations. If the lifetime of an expectation is associated with the life of the moved-from object, your test will likely fail, since the expectation object would then be destroyed before it has been satisfied. Example:

class movable
{
public:
  static constexpr bool trompeloeil_movable_mock = true;
  
  MAKE_MOCK0(func, void());
};

movable setup()
{
  movable obj;
  REQUIRE_CALL(obj, func());
  return obj;
  // Expectation dies here, unsatisfied, failing the test
}

test(...)
{
  movable obj = setup(); // test fails when returning from setup()
  ...
}

Using NAMED_REQUIRE_CALL(), NAMED_ALLOW_CALL() or NAMED_FORBID_CALL() can help, since they make the expectation life times more visible.