Unit test strategy to move / copy constructors?

I want to write unit tests to test the constructors of move / copy / settings of some classes that I am writing. I want to make sure that the resources are handled appropriately, that the ctor call is called when I expect it to be called instead of the ctor copy, and vice versa.

The problem is that I do not want to mess with the class code to check this. So, is there a way to find out from the test code outside the class when the transition or copy / assignment was called?

What is the general strategy for unit-test copy / move ctors / assignments?

PD: I use Catch block testing, so please provide an answer that can be implemented in Catch.

+7
unit-testing c ++ 11
source share
1 answer

I never used Catch, so I can not imagine a working example.

However, I do unit test classes with complex copy / move constructors (e.g. using deep copies, std::unique_ptr , etc.) by testing class methods on moved / copied objects.

For example, if I have a class as follows:

 // constructor Foo::Foo(int i) : privateMember(i) {}; // some function that operates on this private member int Foo::bar() { return privateMember + 5 }; 

I will have a test for the bar() method, but then duplicate it for the move, copy, etc. constructors. You can easily complete the original tests three or four times.

I do not expose member variables. If you do, you can use the "same" test functions (assuming Catch supports this). For example, make sure that a deep copy creates a unique copy (i.e. does not point to the original object).

Update

You seem to be more worried about the correct constructor / assignment of move or copy being called. If you just want to โ€œmove destinationโ€ or some other identifier, I donโ€™t know what to offer.

When I test the copy, I am sure that I am copying the object to my unit test and then calling functions that depend on shallow / deep copies of the member variables. This is the same when I test the movement. In some scenarios, you can run tests on the source object (for example, check that the vector instance variable now has a size of zero after moving).

I force the move constructor as follows:

 Foo foo(); Foo bar(std::move(foo)); 

I force the move destination as follows:

 Foo foo(); Foo bar(); bar = std::move(foo); 

I force the copy constructor as follows:

 Foo foo(); Foo bar(foo); 

I force the copy as follows:

 Foo foo(); Foo bar(); bar = foo; 

If you really need it, you can inherit from some debugging virtual class that provides an enum class field. In your debug assembly, the field is populated with the corresponding enumeration value (MoveConstructor). This field is open, so you can check it after copying / moving. Make sure you populate it in your copy and move constructor constructs.

+2
source share

All Articles