gmock ElementsAreArray() Matcher在gmock- Matcher .h中给出编译错误

gmock ElementsAreArray() Matcher gives compiler errors in gmock-matchers.h

本文关键字:Matcher 错误 编译 gmock- ElementsAreArray gmock      更新时间:2023-10-16

我正在做一些测试,这样我就可以重构一个旧的c++项目。我正在尝试使用gmock匹配器ElementsAreArray()匹配两个数组。

EXPECT_THAT(value_instance.value, ::testing::ElementsAreArray(var_array));

value_instance的地方。value是指向C数组的指针。

但是,当我在测试中编译这行代码时,我从gmock-matchers.h文件中得到以下错误输出:
Error   1   error C2510: 'type' : left of '::' must be a class/struct/union s:repo_filegmock-1.6.0includegmockgmock-matchers.h 2535    1   Project_Tests
Error   2   error C2146: syntax error : missing ';' before identifier 'Element' s:repo_filegmock-1.6.0includegmockgmock-matchers.h 2536    1   Project_Tests
Error   3   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int   s:repo_filegmock-1.6.0includegmockgmock-matchers.h 2536    1   Project_Tests
Error   4   error C2065: 'Element' : undeclared identifier  s:repo_filegmock-1.6.0includegmockgmock-matchers.h 2536    1   Project_Tests
Error   5   error C2825: 'testing::internal::ElementsAreMatcherImpl<Container>::StlContainer': must be a class or namespace when followed by '::'   s:repo_filegmock-1.6.0includegmockgmock-matchers.h 2399    1   Project_Tests
Error   6   error C2039: 'value_type' : is not a member of '`global namespace'' s:repo_filegmock-1.6.0includegmockgmock-matchers.h 2399    1   Project_Tests
Error   7   error C2146: syntax error : missing ';' before identifier 'Element' s:repo_filegmock-1.6.0includegmockgmock-matchers.h 2399    1   Project_Tests
Error   8   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int   s:repo_filegmock-1.6.0includegmockgmock-matchers.h 2399    1   Project_Tests
Error   9   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int   s:repo_filegmock-1.6.0includegmockgmock-matchers.h 2502    1   Project_Tests
Error   10  error C2146: syntax error : missing ',' before identifier 'Element' s:repo_filegmock-1.6.0includegmockgmock-matchers.h 2502    1   Project_Tests
Error   11  error C2065: 'Element' : undeclared identifier  s:repo_filegmock-1.6.0includegmockgmock-matchers.h 2502    1   Project_Tests
Error   12  error C2059: syntax error : '>' s:repo_filegmock-1.6.0includegmockgmock-matchers.h 2502    1   Project_Tests
Error   13  error C2143: syntax error : missing ';' before '}'  s:repo_filegmock-1.6.0includegmockgmock-matchers.h 2506    1   Project_Tests
Error   14  error C1004: unexpected end-of-file found   s:repo_filegmock-1.6.0includegmockgmock-matchers.h 2506    1   Project_Tests

我可能错过了一些非常愚蠢的东西,但我似乎找不到问题所在。

#include <cstring>    
#include "gtest/gtest.h"
#include "gmock/gmock.h"
//This is a stripped down version of The Class under test
enum {
    VAL_TYPE_UNKNOWN, VAL_TYPE_INT, VAL_TYPE_BOOL, VAL_TYPE_ARRAY
};      
class ClassUnderTest
{
  public:
    int alloc_len;
    int len;
    int type;
    long i_value;
    unsigned char *value;    
    ClassUnderTest (void)
    {
      alloc_len = 0;
      len = 0;
      value = 0;
      i_value = 0;
      type = VAL_TYPE_INT;
    }  
    ~ClassUnderTest (void)
    {
      if (value)
      {
        delete [] value;
        value = 0;
      }
    }              
    void Init (void *val,  int v_len)
    {
      NewLength(v_len);
      if (val)
        memcpy(value, val, v_len);
      type = VAL_TYPE_ARRAY;
    }  
    void NewLength (int new_len)
    {
      unsigned char *old;
      if ((new_len > alloc_len) || (new_len == 0))
      {
        old = value;
        value = 0;
        if (new_len > 0)
        {
          value = new unsigned char [new_len];
          memset(value, 0, new_len);
        }
        alloc_len = new_len;
        if (old)
        {
          if (value)
            memcpy(value, old, len);
          delete [] old;
        }
      }
      else if (new_len > len)
        memset(value+len, 0, new_len-len);
      len = new_len;
    }                                         
}                      
//this fails with the error list above
TEST(ClassUnderTestTests, TestInit)
{
  ClassUnderTest value_instance;
  unsigned char var_array[] = {1, 2, 3, 4, 5};
  value_instance.Init((void *)var_array, sizeof(var_array));
  EXPECT_EQ(value_instance.len, sizeof(var_array));
  EXPECT_EQ(value_instance.i_value, 0);
  EXPECT_EQ(value_instance.type, VAL_TYPE_ARRAY);
  EXPECT_THAT(value_instance.value, testing::ElementsAreArray(var_array));
}                            

//This example works However the code above does not
TEST(ClassUnderTestTests, ElementsAreArrayFailure)
{
  int array1[] = {1, 2, 3, 4, 5};
  int array2[] = {1, 2, 3, 4, 5};
  EXPECT_THAT(array1, testing::ElementsAreArray(array2));
}                                    
int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

需要对指向c数组的指针解引用。

EXPECT_THAT(*value_instance.value, ::testing::ElementsAreArray(var_array));
//          ^--- dereference the C-array

更新:

好了,现在看了你的代码,我想说value_instance.value是一个动态分配的数组,而不是指向C数组的指针(参见comp.lang.c关于数组和指针的常见问题解答)。

因此,简单的修复方法是交换EXPECT_THAT(value, matcher)宏中的参数。在这种情况下,值不能只是一个指针,你需要给它一个std::类容器(例如一个C数组)。然而,ElementsAreArray函数可以处理传递给动态分配的数组,假设您也传递给它数组的大小(因为它无法推断)。

EXPECT_THAT(var_array,
            testing::ElementsAreArray(value_instance.value, value_instance.len));

与其将参数的顺序交换给EXPECT_THAT,还不如从value_instance.value构造一个临时的vector,并将其作为值传递:

std::vector<unsigned char> value_copy(value_instance.value,
                                      value_instance.value + value_instance.len);
EXPECT_THAT(value_copy, testing::ElementsAreArray(var_array));