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
This commit is contained in:
Abseil Team 2022-04-28 14:41:12 -07:00 committed by Copybara-Service
parent 830fb56728
commit 8ded48c37b

View File

@ -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:
Imagine you have a mock function that takes an object of type `Foo`, which has
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 ```cpp
using ::testing::Matcher;
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 {
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