How to use ElementsAreArray with C-Style arrays.

5,407 views
Skip to first unread message

Dave Rathnow

unread,
Jan 19, 2016, 6:42:34 PM1/19/16
to Google C++ Mocking Framework

I've been trying to figure out how to match a C-style array argument using ElementsAreArray but I haven't been having a lot of luck.  I've read through Cookbook and all the posts I can find about ElementsAreArray but I'm still stumped.

My mock object looks like this:

class MockFoo : public Foo {
MOCK_CONST_METHOD2(demandPoll, ActionResult*(const u32* pollsetIds, int count));
}


My test case looks like this:

static const u32 EXPECTED_PIDS[] = {1, 2};

MockFoo foo;

EXPECT_CALL(foo, demandPoll(ElementsAreArray(EXPECTED_PIDS, 2), 2)).WillOnce(Return(NULL));

In case your wondering, u32 is:

typedef unsigned long u32;

When I compile this, I get these errors:

/usr/local/include/gmock/gmock-matchers.h: In member function ‘testing::internal::ElementsAreArrayMatcher<T>::operator testing::Matcher<T>() const [with Container = const u32*, T = long unsigned int]’:
SitesActionHandlerTest.cpp:53:   instantiated from here
/usr/local/include/gmock/gmock-matchers.h:2534: error: ‘const u32*’ is not a class, struct, or union type
/usr/local/include/gmock/gmock-matchers.h: At global scope:
/usr/local/include/gmock/gmock-matchers.h: In instantiation of ‘testing::internal::ElementsAreMatcherImpl<const u32*>’:
/usr/local/include/gmock/gmock-matchers.h:2536:   instantiated from ‘testing::internal::ElementsAreArrayMatcher<T>::operator testing::Matcher<T>() const [with Container = const u32*, T = long unsigned int]’
SitesActionHandlerTest.cpp:53:   instantiated from here
/usr/local/include/gmock/gmock-matchers.h:2399: error: ‘const u32*’ is not a class, struct, or union type
/usr/local/include/gmock/gmock-matchers.h:2502: error: ‘const u32*’ is not a class, struct, or union type
/usr/local/include/gmock/gmock-matchers.h: In constructor ‘testing::internal::ElementsAreMatcherImpl<Container>::ElementsAreMatcherImpl(InputIter, size_t) [with InputIter = const long unsigned int*, Container = const u32*]’:
/usr/local/include/gmock/gmock-matchers.h:2536:   instantiated from ‘testing::internal::ElementsAreArrayMatcher<T>::operator testing::Matcher<T>() const [with Container = const u32*, T = long unsigned int]’
SitesActionHandlerTest.cpp:53:   instantiated from here
/usr/local/include/gmock/gmock-matchers.h:2405: error: using invalid field ‘testing::internal::ElementsAreMatcherImpl<Container>::matchers_’
/usr/local/include/gmock/gmock-matchers.h:2408: error: using invalid field ‘testing::internal::ElementsAreMatcherImpl<Container>::matchers_’
/usr/local/include/gmock/gmock-matchers.h:2408: error: ‘const u32*’ is not a class, struct, or union type
/usr/local/include/gmock/gmock-actions.h: In constructor ‘testing::internal::ReturnAction<R>::Impl<F>::Impl(R) [with F = zios::web::ActionResult* ()(const u32*, int), R = int]’:
/usr/local/include/gmock/gmock-actions.h:472:   instantiated from ‘testing::internal::ReturnAction<R>::operator testing::Action<Func>() const [with F = zios::web::ActionResult* ()(const u32*, int), R = int]’
SitesActionHandlerTest.cpp:53:   instantiated from here
/usr/local/include/gmock/gmock-actions.h:491: error: no matching function for call to ‘ImplicitCast_(int&)’
/usr/local/include/gmock/gmock-matchers.h: In member function ‘bool testing::internal::ElementsAreMatcherImpl<Container>::MatchAndExplain(Container, testing::MatchResultListener*) const [with Container = const u32*]’:
SitesActionHandlerTest.cpp:73:   instantiated from here
/usr/local/include/gmock/gmock-matchers.h:2451: error: request for member ‘size’ in ‘stl_container’, which is of non-class type ‘const u32* const’
SitesActionHandlerTest.cpp:73:   instantiated from here
/usr/local/include/gmock/gmock-matchers.h:2463: error: ‘const u32*’ is not a class, struct, or union type
SitesActionHandlerTest.cpp:73:   instantiated from here
/usr/local/include/gmock/gmock-matchers.h:2463: error: ‘const u32*’ is not a class, struct, or union type
/usr/local/include/gmock/gmock-matchers.h:2468: error: using invalid field ‘testing::internal::ElementsAreMatcherImpl<Container>::matchers_’
/usr/local/include/gmock/gmock-matchers.h:2463: error: ‘const u32*’ is not a class, struct, or union type
/usr/local/include/gmock/gmock-matchers.h: In member function ‘void testing::internal::ElementsAreMatcherImpl<Container>::DescribeTo(std::ostream*) const [with Container = const u32*]’:
SitesActionHandlerTest.cpp:73:   instantiated from here
/usr/local/include/gmock/gmock-matchers.h:2418: error: using invalid field ‘testing::internal::ElementsAreMatcherImpl<Container>::matchers_’
SitesActionHandlerTest.cpp:73:   instantiated from here
/usr/local/include/gmock/gmock-matchers.h:2423: error: using invalid field ‘testing::internal::ElementsAreMatcherImpl<Container>::matchers_’
/usr/local/include/gmock/gmock-matchers.h: In member function ‘void testing::internal::ElementsAreMatcherImpl<Container>::DescribeNegationTo(std::ostream*) const [with Container = const u32*]’:
SitesActionHandlerTest.cpp:73:   instantiated from here
/usr/local/include/gmock/gmock-matchers.h:2441: error: using invalid field ‘testing::internal::ElementsAreMatcherImpl<Container>::matchers_’
/usr/local/include/gmock/gmock-matchers.h: In member function ‘size_t testing::internal::ElementsAreMatcherImpl<Container>::count() const [with Container = const u32*]’:
/usr/local/include/gmock/gmock-matchers.h:2452:   instantiated from ‘bool testing::internal::ElementsAreMatcherImpl<Container>::MatchAndExplain(Container, testing::MatchResultListener*) const [with Container = const u32*]’
SitesActionHandlerTest.cpp:73:   instantiated from here
/usr/local/include/gmock/gmock-matchers.h:2501: error: using invalid field ‘testing::internal::ElementsAreMatcherImpl<Container>::matchers_’
make: *** [Debug/SitesActionHandlerTest.o] Error 1

Billy Donahue

unread,
Jan 19, 2016, 7:05:14 PM1/19/16
to Dave Rathnow, Google C++ Mocking Framework
On Tue, Jan 19, 2016 at 6:42 PM, Dave Rathnow <drat...@gmail.com> wrote:

I've been trying to figure out how to match a C-style array argument using ElementsAreArray but I haven't been having a lot of luck.  I've read through Cookbook and all the posts I can find about ElementsAreArray but I'm still stumped.

My mock object looks like this:

class MockFoo : public Foo {
MOCK_CONST_METHOD2(demandPoll, ActionResult*(const u32* pollsetIds, int count));
}


My test case looks like this:

static const u32 EXPECTED_PIDS[] = {1, 2};

MockFoo foo;

EXPECT_CALL(foo, demandPoll(ElementsAreArray(EXPECTED_PIDS, 2), 2)).WillOnce(Return(NULL));


Does the situation improve if you just have ElementsAreArray(EXPECTED_PIDS) and leave off the 2?
 

--

---
You received this message because you are subscribed to the Google Groups "Google C++ Mocking Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/googlemock/bb750cba-2655-4b10-b806-86c75f6cb4b3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dave Rathnow

unread,
Jan 19, 2016, 7:23:34 PM1/19/16
to Google C++ Mocking Framework, drat...@gmail.com

No.  I've tried both ways and I get the same error.

Corey Kosak

unread,
Jan 19, 2016, 8:39:29 PM1/19/16
to Dave Rathnow, Google C++ Mocking Framework
Hiya,

This works for me. (PS: in the future if you could post a more-complete code snippet it could save us some time (at least for my sake) :-)



using testing::Args;
using testing::ElementsAreArray;
using testing::Return;
using testing::_;

struct ActionResult {};
typedef unsigned long u32;

class Foo {
public:
  virtual ~Foo() {}
  virtual ActionResult *demandPoll(const u32* pollSetIds, int count) const;
};

class MockFoo : public Foo {
public:
  MOCK_CONST_METHOD2(demandPoll, ActionResult*(const u32* pollsetIds, int count));
};

static u32 EXPECTED_PIDS[] = {1, 2};

TEST(Blah, Blah) {
  MockFoo foo;

  EXPECT_CALL(foo, demandPoll(_, _)).With(Args<0,1>(ElementsAreArray(EXPECTED_PIDS))).WillOnce(Return(nullptr));


Dave Rathnow

unread,
Jan 20, 2016, 11:13:32 AM1/20/16
to Google C++ Mocking Framework, drat...@gmail.com
Thanks you Corey!  That worked.

Any idea why the other from fails?

Corey Kosak

unread,
Jan 20, 2016, 12:34:52 PM1/20/16
to Dave Rathnow, Google C++ Mocking Framework
I'm not a super-expert on this, so my answer is unfortunately going to be a little awkward. My "analysis" is to break down this expression:

demandPoll(ElementsAreArray(EXPECTED_PIDS, 2), 2)

The second "2" is a matcher that will match the 1-th argument, so that's a straightforward match and we're done with that.

The "ElementsAreArray(EXPECTED_PIDS, 2)" is a matcher set up to match the 0-th argument. It is an array of length 2. However the 0-th argument that it is being compared with, namely a const u32*, doesn't have an associated length. gMock doesn't know what the array length of that const u32* is (even though you've tried mightily to tell it) and it's not going to assume 2 just because that's what the matcher is carrying. Put another way, gMock knows the length of one of the arrays but not the other.

Then I tried to figure out how to actually tell gMock what it needs. I started reading https://github.com/google/googletest/blob/master/googlemock/docs/CheatSheet.md under the "These matchers also match:" section and it looked like the second bullet point was exactly your use case.

Does that make sense? It's about the best explanation I have; maybe some gMock wizard wants to chime in :-)



Dave Rathnow

unread,
Jan 20, 2016, 2:14:39 PM1/20/16
to Google C++ Mocking Framework, drat...@gmail.com

That's a pretty good explanation and was along the lines of what I was thinking.  I did this because of the this example given in the Cookbook:


// ElementsAreArray accepts an array of element values.
  const int expected_vector1[] = { 1, 5, 2, 4, ... };
  EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector1)));

I'm pretty sure this is exactly what I was doing but it wouldn't compile.  Is this an error in the doc?  Perhaps one of the developers can answer that question one day.

In any case, thanks again!

Corey Kosak

unread,
Jan 20, 2016, 5:47:18 PM1/20/16
to Dave Rathnow, Google C++ Mocking Framework
Yeah, that whole section of the documentation refers to the case where the argument being matched is an STL container. It's possible that the text could be made clearer about the roles of matcher vs matchee.

Reply all
Reply to author
Forward
0 new messages