c++ - 如何在 EXPECT_CALL 中使用 ElementsAreArray 匹配器

标签 c++ googletest googlemock

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_;

最佳答案

我认为使用 ElementsAreArray(或任何其他 cointainer 匹配器)不可能做到这一点

如果我阅读 documentation,我不是 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)));

See it online

关于c++ - 如何在 EXPECT_CALL 中使用 ElementsAreArray 匹配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56791171/

相关文章:

c++ - 获取C++中表达式的含义

c++ - Google Mocks 测试输出到 XML 不起作用

c++ - 谷歌在同一解决方案中测试多个 C++ 项目

c++ - 如何模拟没有类的函数?

c++ - 使用 GMOCK 在 C++ 中模拟新运算符

c++ - 寻找一种更有效的方法来在 C++ 中生成/打印 "progress bar"

c++ - 帮助我理解这个 C++ for 循环的终止参数

c++ - 无法在 VS 对话框编辑器中更改组合框的高度

c++ - 尝试使用谷歌测试编译 main 时获取 "multiple definition of func_name"

c++ - CMake:如何指定 ctest 应在其中查找可执行文件的目录?