Как использовать совпадение ElementsAreArray в EXPECT_CALL - PullRequest
1 голос
/ 27 июня 2019
EXPECT_CALL(*backendHttpResponseStatusLogger, LogValue(0, ElementsAreArray({ "ip1:p1", "pool1", "setting1", "1xx" }))).Times(1);

Дает мне ошибку компиляции, как показано ниже. Что бы правильно использовать его. сигнатура функции LogValue void(int64_t, const string[])

 /appgwtlib/googletest/googletest-release-1.8.0/googlemock/include/gmock/gmock-matchers.h: In instantiation of 'class testing::internal::ElementsAreMatcherImpl<const std::__cxx11::basic_string<char>*>':
    /appgwtlib/googletest/googletest-release-1.8.0/googlemock/include/gmock/gmock-matchers.h:3532:23:   required from 'testing::internal::ElementsAreArrayMatcher<T>::operator testing::Matcher<T>() const [with Container = const std::__cxx11::basic_string<char>*; T = const char*]'
    NginxMetricHandlerTests.cpp:85:3:   required from here
    /appgwtlib/googletest/googletest-release-1.8.0/googlemock/include/gmock/gmock-matchers.h:3114:45: error: 'testing::internal::ElementsAreMatcherImpl<const std::__cxx11::basic_string<char>*>::StlContainer {aka const std::__cxx11::basic_string<char>*}' is not a class, struct, or union type
       typedef typename StlContainer::value_type Element;
                                                 ^
    /appgwtlib/googletest/googletest-release-1.8.0/googlemock/include/gmock/gmock-matchers.h:3248:43: error: 'testing::internal::StlContainerView<const std::__cxx11::basic_string<char>*>::type {aka const std::__cxx11::basic_string<char>*}' is not a class, struct, or union type
       ::std::vector<Matcher<const Element&> > matchers_;

1 Ответ

2 голосов
/ 27 июня 2019

Я не думаю, что это возможно сделать с помощью ElementsAreArray (или любого другого сопоставителя монетодержателя)

Я не на 100%, если правильно прочитал документацию , но кажется, что массив в стиле C должен передаваться либо по ссылке, либо вместе с его размером, чтобы сработали сопоставители.

Обратите внимание на эту ошибку:

error: 'testing::internal::ElementsAreMatcherImpl<const std::__cxx11::basic_string<char>*>::StlContainer {aka const std::__cxx11::basic_string<char>*}' is not a class, struct, or union type

Член внутреннего класса GMock называется StlContainer, но вместо этого он std::string*.

Это не сработает, если вы не передадите количество элементов в массиве (что вы, вероятно, должны делать в любом случае, когда имеете дело с массивами в стиле C).


Вместо этого вы можете написать свой собственный механизм сопоставления, который будет небезопасно (без знания реального размера массива) сравнивать элементы:

MATCHER_P(CStyleArrayEqual, arrayToCompare, "")
{
    int i = 0;
    for(const auto& elem: arrayToCompare)
    {
        //very, VERY unsafe! You don't know the length of arg!
        //std::initializer_list doesn't have operator[], have to resort to other methods
        if(arg[i] != elem)
            return false;
        ++i;
    }
    return true;
}

Однако для этого требуется передать действительный объект ( braced-init-lists не работает с шаблонами):

EXPECT_CALL(*backendHttpResponseStatusLogger, LogValue(0, CStyleArrayEqual(std::vector<std::string>{"1", "2"})));

Чтобы избежать явного присвоения имени типу, вы можете предварительно объявить переменную:

auto arrayToMatch {"1", "2"}; //type is std::initializer_list<std::string>
EXPECT_CALL(*backendHttpResponseStatusLogger, LogValue(0, CStyleArrayEqual(arrayToMatch)));

Посмотреть онлайн

...