Search code examples
c++googlemock

Why do I need the second argument?


I have a method

class FooInterface {
    bool put(uint8_t* array, unsigned array_length);
}

The test needs to verify that array of {1, 2, 3, 4, 5}, which has 5 elements is being passed to the put In My TEST_F(), I have the following code.

uint8_t arr[5] = {1, 2, 3, 4, 5};  // Values for 'array' the out parameter

MockFoo foo;
FooInterface* fooI = &foo;

EXPECT_CALL(foo, put(_, 5))
    .With(Args<0,1>(ElementsAreArray(arr, 5)));

This seems to work, but it is driving me crazy because, it seems like instead of Args<0,1>, I should have Args<0> since I am matching array for the first parameter and the array size is set to 5. Changing to:

EXPECT_CALL(BFO, put(_, 5))
    .With(Args<0>(ElementsAreArray(arr, 5)));  // Here is 'Args<0>'

Produces these errors:

/home/sporty/ws-ccs/googletest/googlemock/include/gmock/gmock-matchers.h:3114:34: error: no type named 'value_type' in 'std::tr1::tuple<const unsigned char *>'                                                                                                                                                                                                              
  typedef typename StlContainer::value_type Element;                                                                                                                                                                                                                                                                                                                         
          ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~                                                                                                                                                                                                                                                                                                                                  
/home/sporty/ws-ccs/googletest/googlemock/include/gmock/gmock-matchers.h:3532:28: note: in instantiation of template class 'testing::internal::ElementsAreMatcherImpl<const std::tr1::tuple<const unsigned char *> &>' requested here                                                                                                                                        
    return MakeMatcher(new ElementsAreMatcherImpl<Container>(                                                                                                                                                                                                                                                                                                                
                           ^                                                                                                                                                                                                                                                                                                                                                 
/home/sporty/ws-ccs/googletest/googlemock/include/gmock/gmock-matchers.h:555:12: note: in instantiation of function template specialization 'testing::internal::ElementsAreArrayMatcher<unsigned char>::operator Matcher<const std::tr1::tuple<const unsigned char *> &>' requested here                                                                                     
    return polymorphic_matcher_or_value;                                                                                                                                                                                                                                                                                                                                     
           ^                                                                                                                                                                                                                                                                                                                                                                 
/home/sporty/ws-ccs/googletest/googlemock/include/gmock/gmock-matchers.h:531:12: note: in instantiation of member function 'testing::internal::MatcherCastImpl<const std::tr1::tuple<const unsigned char *> &, testing::internal::ElementsAreArrayMatcher<unsigned char> >::CastImpl' requested here                                                                         
    return CastImpl(                                                                                                                                                                                                                                                                                                                                                         
           ^                                                                                                                                                                                                                                                                                                                                                                 
/home/sporty/ws-ccs/googletest/googlemock/include/gmock/gmock-matchers.h:628:45: note: in instantiation of member function 'testing::internal::MatcherCastImpl<const std::tr1::tuple<const unsigned char *> &, testing::internal::ElementsAreArrayMatcher<unsigned char> >::Cast' requested here                                                                             
    return internal::MatcherCastImpl<T, M>::Cast(polymorphic_matcher_or_value);                                                                                                                                                                                                                                                                                              
                                            ^                                                                                                                                                                                                                                                                                                                                
/home/sporty/ws-ccs/googletest/googlemock/include/gmock/gmock-matchers.h:666:34: note: in instantiation of function template specialization 'testing::SafeMatcherCastImpl<const std::tr1::tuple<const unsigned char *> &>::Cast<testing::internal::ElementsAreArrayMatcher<unsigned char> >' requested here                                                                  
  return SafeMatcherCastImpl<T>::Cast(polymorphic_matcher);                                                                                                                                                                                                                                                                                                                  
                                 ^                                                                                                                                                                                                                                                                                                                                           
/home/sporty/ws-ccs/googletest/googlemock/include/gmock/gmock-generated-matchers.h:221:24: note: in instantiation of function template specialization 'testing::SafeMatcherCast<const std::tr1::tuple<const unsigned char *> &, testing::internal::ElementsAreArrayMatcher<unsigned char> >' requested here                                                                  
      : inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}                                                                                                                                                                                                                                                                                               
                       ^                                                                                                                                                                                                                                                                                                                                                     
/home/sporty/ws-ccs/googletest/googlemock/include/gmock/gmock-generated-matchers.h:288:28: note: in instantiation of function template specialization 'testing::internal::ArgsMatcherImpl<const std::tr1::tuple<const unsigned char *, unsigned int> &, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1>::ArgsMatcherImpl<testing::internal::ElementsAreArrayMatcher<unsigned char> >' 
    return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, k0, k1, k2, k3, k4, k5,                                                                                                                                                                                                                                                                                                
                           ^                                                                                                                                                                                                                                                                                                                                                 
/home/sporty/ws-ccs/hw_1_5/miwt-os/coap/unittest/cbor_encoder_test.cpp:176:15: note: in instantiation of function template specialization 'testing::internal::ArgsMatcher<testing::internal::ElementsAreArrayMatcher<unsigned char>, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1>::operator Matcher<const std::tr1::tuple<const unsigned char *, unsigned int> &>' requested here  
        .With(Args<0>(ElementsAreArray(arr, 5)));
              ^  

Solution

  • A pointer is not an array; it is simply an address to a spot in memory. The system has zero way of knowing how long the memory you reserved for the array is. The second argument is specifically for that purpose. You know when you create it how long it is so you have to pass that information along.

    However, unless you are forbidden to do so, I would recommend taking the time to learn how to use templates to handle your arrays and array type structures. The std::array is very nice and has all kinds of bells and whistles you can use. Best of all it handles all of the hassle that goes with maintaining your array.