0

Consider the following test that simply takes in two numbers and tests if their sum is equal to 5.

struct IntHolder
{
  int x;
  int y;
  char* arr;
  IntHolder(int x, int y)
  :x(x), y(y)
  {
    arr = new char[3] {1, 2, 3};
  }

  ~IntHolder()
  {
    delete[] arr;
  }
};

class TestSum : public ::testing::TestWithParam<IntHolder> {};

TEST_P(TestSum, SumsEqualToTest)
{
  EXPECT_EQ(5, GetParam().x + GetParam().y);
}

INSTANTIATE_TEST_CASE_P(SumInputs, TestSum, ::testing::Values(
  IntHolder(4, 1),
  IntHolder(1, 2)
));

Without the char* arr, this test functions as normal, and using a struct seems to be the only way to use value-parameterized tests in Google Test when having one than one parameter.

However, if that struct needs to initialize any elements with new (in this case arr), a segfault occurs because it seems that the destructors are called many more times than the constructors (this was found via debugging).

Why does this happen? Is there a better way to do multi-value-parameterized tests in Google Test? Note that I am not using C++11.

Edit:

Thanks, the correct code would be:

struct IntHolder
{
  int x;
  int y;
  char* arr;
  IntHolder(int x, int y)
  :x(x), y(y)
  {
    arr = new char[3] {1, 2, 3};
  }

  IntHolder(const IntHolder& that)
  :x(that.x), y(that.y)
  {
    arr = new char[3] {
      that.arr[0],
      that.arr[1],
      that.arr[2],
    };
  }

  IntHolder& operator=(const IntHolder& that)
  {
    x = that.x;
    y = that.y;
    arr[0] = that.arr[0];
    arr[1] = that.arr[1];
    arr[2] = that.arr[2];
    return *this;
  }

  ~IntHolder()
  {
    delete[] arr;
  }
};

class TestSum : public ::testing::TestWithParam<IntHolder> {};

TEST_P(TestSum, SumsEqualToTest)
{
  EXPECT_EQ(5, GetParam().x + GetParam().y);
}

INSTANTIATE_TEST_CASE_P(SumInputs, TestSum, ::testing::Values(
  IntHolder(4, 1),
  IntHolder(1, 2)
));
Phylliida
  • 4,217
  • 3
  • 22
  • 34
  • You need to provide correct copy constructors and assignment operators to avoid plain copies of raw pointers, that will be deleted multiple times, if you have copies of your `IntHolder` (and you have such) that go out uf scope. – πάντα ῥεῖ Jun 16 '15 at 16:48
  • 1
    Ah, awesome, thanks! That fixed it =) – Phylliida Jun 16 '15 at 16:56

0 Answers0