Skip to content

Commit 4902ea2

Browse files
zhanyongwancopybara-github
authored andcommitted
Clarify the polymorphic matcher concept and explain how to define a composite matcher.
Many gtest users aren't aware that a polymorphic matcher is not actually a `testing::Matcher<>` and thus doesn't know how to describe itself. Clarify this. Also adds a recipe on how to define a composite matcher. In particular, explain how the composite matcher can describe itself in terms of the description(s) of its sub-matcher(s). PiperOrigin-RevId: 735840759 Change-Id: I26cff6179349aa739fc7fdd528a2f5308d18c189
1 parent 4ee4b17 commit 4902ea2

File tree

1 file changed

+39
-6
lines changed

1 file changed

+39
-6
lines changed

docs/gmock_cook_book.md

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3567,10 +3567,15 @@ just based on the number of parameters).
35673567

35683568
### Writing New Monomorphic Matchers
35693569

3570-
A matcher of argument type `T` implements the matcher interface for `T` and does
3571-
two things: it tests whether a value of type `T` matches the matcher, and can
3572-
describe what kind of values it matches. The latter ability is used for
3573-
generating readable error messages when expectations are violated.
3570+
A matcher of type `testing::Matcher<T>` implements the matcher interface for `T`
3571+
and does two things: it tests whether a value of type `T` matches the matcher,
3572+
and can describe what kind of values it matches. The latter ability is used for
3573+
generating readable error messages when expectations are violated. Some matchers
3574+
can even explain why it matches or doesn't match a certain value, which can be
3575+
helpful when the reason isn't obvious.
3576+
3577+
Because a matcher of type `testing::Matcher<T>` for a particular type `T` can
3578+
only be used to match a value of type `T`, we call it "monomorphic."
35743579

35753580
A matcher of `T` must declare a typedef like:
35763581

@@ -3662,8 +3667,16 @@ instead of `std::ostream*`.
36623667

36633668
### Writing New Polymorphic Matchers
36643669

3665-
Expanding what we learned above to *polymorphic* matchers is now just as simple
3666-
as adding templates in the right place.
3670+
Unlike a monomorphic matcher, which can only be used to match a value of a
3671+
particular type, a *polymorphic* matcher is one that can be used to match values
3672+
of multiple types. For example, `Eq(5)` is a polymorhpic matcher as it can be
3673+
used to match an `int`, a `double`, a `float`, and so on. You should think of a
3674+
polymorphic matcher as a *matcher factory* as opposed to a
3675+
`testing::Matcher<SomeType>` - itself is not an actual matcher, but can be
3676+
implicitly converted to a `testing::Matcher<SomeType>` depending on the context.
3677+
3678+
Expanding what we learned above to polymorphic matchers is now as simple as
3679+
adding templates in the right place.
36673680

36683681
```cpp
36693682

@@ -3789,6 +3802,26 @@ virtual.
37893802
Like in a monomorphic matcher, you may explain the match result by streaming
37903803
additional information to the `listener` argument in `MatchAndExplain()`.
37913804

3805+
### Implementing Composite Matchers {#CompositeMatchers}
3806+
3807+
Sometimes we want to define a matcher that takes other matchers as parameters.
3808+
For example, `DistanceFrom(target, m)` is a polymorphic matcher that takes a
3809+
matcher `m` as a parameter. It tests that the distance from `target` to the
3810+
value being matched satisfies sub-matcher `m`.
3811+
3812+
If you are implementing such a composite matcher, you'll need to generate the
3813+
description of the matcher based on the description(s) of its sub-matcher(s).
3814+
You can see the implementation of `DistanceFrom()` in
3815+
`googlemock/include/gmock/gmock-matchers.h` for an example. In particular, pay
3816+
attention to `DistanceFromMatcherImpl`. Notice that it stores the sub-matcher as
3817+
a `const Matcher<const Distance&> distance_matcher_` instead of a polymorphic
3818+
matcher - this allows it to call `distance_matcher_.DescribeTo(os)` to describe
3819+
the sub-matcher. If the sub-matcher is stored as a polymorphic matcher instead,
3820+
it would not be possible to get its description as in general polymorphic
3821+
matchers don't know how to describe themselves - they are matcher factories
3822+
instead of actual matchers; only after being converted to `Matcher<SomeType>`
3823+
can they be described.
3824+
37923825
### Writing New Cardinalities
37933826

37943827
A cardinality is used in `Times()` to tell gMock how many times you expect a

0 commit comments

Comments
 (0)