Я работаю над некоторыми тестами, чтобы я мог провести рефакторинг старого проекта C ++. Я пытаюсь сопоставить два массива с помощью gmock matcher 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_file\gmock-1.6.0\include\gmock\gmock-matchers.h 2535 1 Project_Tests
Error 2 error C2146: syntax error : missing ';' before identifier 'Element' s:\repo_file\gmock-1.6.0\include\gmock\gmock-matchers.h 2536 1 Project_Tests
Error 3 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int s:\repo_file\gmock-1.6.0\include\gmock\gmock-matchers.h 2536 1 Project_Tests
Error 4 error C2065: 'Element' : undeclared identifier s:\repo_file\gmock-1.6.0\include\gmock\gmock-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_file\gmock-1.6.0\include\gmock\gmock-matchers.h 2399 1 Project_Tests
Error 6 error C2039: 'value_type' : is not a member of '`global namespace'' s:\repo_file\gmock-1.6.0\include\gmock\gmock-matchers.h 2399 1 Project_Tests
Error 7 error C2146: syntax error : missing ';' before identifier 'Element' s:\repo_file\gmock-1.6.0\include\gmock\gmock-matchers.h 2399 1 Project_Tests
Error 8 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int s:\repo_file\gmock-1.6.0\include\gmock\gmock-matchers.h 2399 1 Project_Tests
Error 9 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int s:\repo_file\gmock-1.6.0\include\gmock\gmock-matchers.h 2502 1 Project_Tests
Error 10 error C2146: syntax error : missing ',' before identifier 'Element' s:\repo_file\gmock-1.6.0\include\gmock\gmock-matchers.h 2502 1 Project_Tests
Error 11 error C2065: 'Element' : undeclared identifier s:\repo_file\gmock-1.6.0\include\gmock\gmock-matchers.h 2502 1 Project_Tests
Error 12 error C2059: syntax error : '>' s:\repo_file\gmock-1.6.0\include\gmock\gmock-matchers.h 2502 1 Project_Tests
Error 13 error C2143: syntax error : missing ';' before '}' s:\repo_file\gmock-1.6.0\include\gmock\gmock-matchers.h 2506 1 Project_Tests
Error 14 error C1004: unexpected end-of-file found s:\repo_file\gmock-1.6.0\include\gmock\gmock-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 (см. FAQ по comp.lang.c в Массивы и указатели).
Таким образом, простое решение состоит в том, чтобы поменять местами аргументы в EXPECT_THAT(value, matcher)
макро. Значение не может быть просто указателем в этом случае, вам нужно дать ему std::
-подобный контейнер (например, массив C). Тем не менее ElementsAreArray
функция Можно обрабатывать передаваемый динамически распределенный массив, предполагая, что вы также передаете ему размер массива (поскольку он не может быть выведен).
EXPECT_THAT(var_array,
testing::ElementsAreArray(value_instance.value, value_instance.len));
Вместо того, чтобы менять порядок аргументов EXPECT_THAT
Вы могли бы альтернативно построить временный vector
от value_instance.value
и передайте это как значение:
std::vector<unsigned char> value_copy(value_instance.value,
value_instance.value + value_instance.len);
EXPECT_THAT(value_copy, testing::ElementsAreArray(var_array));
Других решений пока нет …