How can I match one element from a C++ tuple using gmock ?
For example let's try to extract the std::string
from a std::tuple<std::string, int>
.
I know I could write a custom matcher like this:
MATCHER_P(match0thOfTuple, expected, "") { return (std::get<0>(arg) == expected); }
But since I found the Pair(m1, m2)
matcher for the std::pair
, I expected also to find something similar for the std::tuple
.
Gmock has Args<N1, N2, ..., Nk>(m)
for selecting a subset of tuple arguments. When using it with just 1 argument, it still expects a tuple matcher. The following attempt does not seem to compile:
struct {
MOCK_METHOD1(mockedFunction, void(std::tuple<std::string, int>&));
} mock;
EXPECT_CALL(mock, mockedFunction(testing::Args<0>(testing::Eq(expectedStringValue))));
And makes my clang give a compilation error like this:
.../gtest/googlemock/include/gmock/gmock-matchers.h:204:60: error: invalid operands to binary expression ('const std::__1::tuple<std::__1::basic_string<char> >' and 'const std::__1::basic_string<char>')
bool operator()(const A& a, const B& b) const { return a == b; }
...
Is there a gmock solution for the std::tuple
similar to the one for the std::pair
, which uses the gmock Pair
matcher?
On 2020-10-15 a matcher for tuples was added to googletest. This new matcher is called FieldsAre
and it is now also mentioned in the matchers reference.
It is used the same as Pair
, the caveat here is that neither can extract a specific element as you had requested.
auto const value = std::tuple{ std::string{ "foo" }, 42, 3.14 };
EXPECT_THAT(value, FieldsAre("foo", 42, 3.14));
// You can use any matcher as usual
EXPECT_THAT(value, FieldsAre(SizeIs(3), Ge(41), Ne(2.71)));
// To "extract" a field you could ignore the others with _
EXPECT_THAT(value, FieldsAre("foo", _, _));