Commit 8ded48c3 authored by Abseil Team's avatar Abseil Team Committed by Copybara-Service
Browse files

Rewrite "Testing a Certain Property of an Object" as "Defining a Custom...

Rewrite "Testing a Certain Property of an Object" as "Defining a Custom Matcher Class", and fix the code examples.

PiperOrigin-RevId: 445252626
Change-Id: I9f038cb669d3da6743606343c2341fc59725d722
parent 830fb567
...@@ -1300,23 +1300,27 @@ What if you have a pointer to pointer? You guessed it - you can use nested ...@@ -1300,23 +1300,27 @@ What if you have a pointer to pointer? You guessed it - you can use nested
`Pointee(Pointee(Lt(3)))` matches a pointer that points to a pointer that points `Pointee(Pointee(Lt(3)))` matches a pointer that points to a pointer that points
to a number less than 3 (what a mouthful...). to a number less than 3 (what a mouthful...).
### Testing a Certain Property of an Object ### Defining a Custom Matcher Class {#CustomMatcherClass}
Sometimes you want to specify that an object argument has a certain property, Most matchers can be simply defined using [the MATCHER* macros](#NewMatchers),
but there is no existing matcher that does this. If you want good error which are terse and flexible, and produce good error messages. However, these
messages, you should [define a matcher](#NewMatchers). If you want to do it macros are not very explicit about the interfaces they create and are not always
quick and dirty, you could get away with writing an ordinary function. suitable, especially for matchers that will be widely reused.
Let's say you have a mock function that takes an object of type `Foo`, which has For more advanced cases, you may need to define your own matcher class. A custom
an `int bar()` method and an `int baz()` method, and you want to constrain that matcher allows you to test a specific invariant property of that object. Let's
the argument's `bar()` value plus its `baz()` value is a given number. Here's take a look at how to do so.
how you can define a matcher to do it:
```cpp Imagine you have a mock function that takes an object of type `Foo`, which has
using ::testing::Matcher; an `int bar()` method and an `int baz()` method. You want to constrain that the
argument's `bar()` value plus its `baz()` value is a given number. (This is an
invariant.) Here's how we can write and use a matcher class to do so:
```cpp
class BarPlusBazEqMatcher { class BarPlusBazEqMatcher {
public: public:
using is_gtest_matcher = void;
explicit BarPlusBazEqMatcher(int expected_sum) explicit BarPlusBazEqMatcher(int expected_sum)
: expected_sum_(expected_sum) {} : expected_sum_(expected_sum) {}
...@@ -1325,23 +1329,24 @@ class BarPlusBazEqMatcher { ...@@ -1325,23 +1329,24 @@ class BarPlusBazEqMatcher {
return (foo.bar() + foo.baz()) == expected_sum_; return (foo.bar() + foo.baz()) == expected_sum_;
} }
void DescribeTo(std::ostream& os) const { void DescribeTo(std::ostream* os) const {
os << "bar() + baz() equals " << expected_sum_; *os << "bar() + baz() equals " << expected_sum_;
} }
void DescribeNegationTo(std::ostream& os) const { void DescribeNegationTo(std::ostream* os) const {
os << "bar() + baz() does not equal " << expected_sum_; *os << "bar() + baz() does not equal " << expected_sum_;
} }
private: private:
const int expected_sum_; const int expected_sum_;
}; };
Matcher<const Foo&> BarPlusBazEq(int expected_sum) { ::testing::Matcher<const Foo&> BarPlusBazEq(int expected_sum) {
return BarPlusBazEqMatcher(expected_sum); return BarPlusBazEqMatcher(expected_sum);
} }
... ...
EXPECT_CALL(..., DoThis(BarPlusBazEq(5)))...; Foo foo;
EXPECT_CALL(foo, BarPlusBazEq(5))...;
``` ```
### Matching Containers ### Matching Containers
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment