单元测试移动/复制构造函数的策略?

bec*_*cko 9 unit-testing c++11

我想编写单元测试来测试我正在编写的某些类的移动/复制构造函数/分配.我想确保资源得到适当处理,当我希望调用move ctor而不是copy ctor时调用它,反之亦然.

问题是我不想乱用类代码来测试它.那么,有没有办法从课外的测试代码中了解移动或复制ctors /赋值?

什么是单元测试复制/移动ctors /赋值的一般策略?

PD:我正在使用Catch单元测试框架,所以请提供一个可以在Catch中实现的答案.

Cla*_*ton 5

I have never used Catch so can't provide a working example.

However, I unit test classes with complicated copy/move constructors (e.g. involving deep copies, std::unique_ptr etc) by testing the class methods on the 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 };
Run Code Online (Sandbox Code Playgroud)

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

I don't expose member variables. If you do then you may be able to use "is same" test functions (assuming Catch supports this). For example, making sure a deep copy creates a unique copy (i.e. doesn't point back to the original object).

Update

You seem to be more concerned that the correct move or copy constructor/assignment is called. If you simply want "move assignment" or some other identifier provided I don't know what to suggest.

When I test copy, I make sure I copy the object in my unit test, then call functions that depend on shallow/deep copies of member variables. This is the same for when I test move. In some scenarios you can run tests on the original object (e.g. test that a vector instance variable now has a size of zero after the move).

I force a move constructor as follows:

Foo foo{};
Foo bar(std::move(foo));
Run Code Online (Sandbox Code Playgroud)

I force a move assignment as follows:

Foo foo{};
Foo bar{};
bar = std::move(foo);
Run Code Online (Sandbox Code Playgroud)

I force a copy constructor as follows:

Foo foo{};
Foo bar(foo);
Run Code Online (Sandbox Code Playgroud)

I force a copy assignment as follows:

Foo foo{};
Foo bar{};
bar = foo;
Run Code Online (Sandbox Code Playgroud)

如果确实需要此功能,则可以从一些暴露枚举类字段的调试虚拟类中继承。在调试版本中,使用适当的枚举值(MoveConstructor)填充该字段。此字段已公开,因此您可以在复制/移动后对其进行测试。确保在复制/移动构造函数/分配方法中填充它。