Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing copy constructr and assignment operator

I am writing unit tests for a few classes (C++), and came across an issue attempting to write a unit test for the copy constructor and assignment operator. A basic thing that could be wrong with either is that a programmer adds a member to the class and then forgets to update the c'ctor and/or operator=.

I could of course write a unit test along the lines of:

class MyClass()
{
public:

    int a, b;
    non_trivial_copyable nasty;

    MyClass& operator=(const MyClass& _r)
    {
        if(this == &r)
          return *this;
        a = _r.a;
        b = _r.b;
        nasty = acquire_non_trivial_copyable();
    }
};


TEST(My_Class_copy_op)
{
  MyClass m1;
  m1.a = m1.b = 2;

  MyClass m2 = m1;
  VERIFY(m2.a == 2);
  VERIFY(m2.b == 2);
}

Very well. now the programmer adds a member c, but doesn't update the operator and test case.

class MyClass()
{
public:
    float c;
// ...
}

The test case will still merrily succeed, even though the operator is now broken.

Now, we could do the following:

TEST(My_Class_copy_op)
{
// Aha! Fails when programmer forgets to update test case to include checking c
   static_assert(sizeof(MyClass) == 8);
// Meh, also fails on an architecture where the size of MyClass happens to be != 8

   // ...
}

I could not find any good information on how to solve this, but sure someone must have ran into this before!? Is is so obvious that I'm missing it completely!?

like image 257
namezero Avatar asked Feb 12 '23 05:02

namezero


1 Answers

Explicitly testing a copy constructor is fine, but it's probably beating around the bush. More often that not, the copy constructor itself is a detail you don't need to explicitly test. What you probably want to do instead is to write a suite of tests that do work on your copied object and make sure that the work comes up with the correct results. Like this:

MyClass a;
// Now initialize a with stuff it needs to do its job

// Copy a into b
MyClass b = a;

// Make b do its job and make sure it succeeds
VERIFY(b.DoWork());
like image 125
mbgda Avatar answered Feb 13 '23 19:02

mbgda