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

Unit testing 单元测试移动/复制构造函数的策略?,unit-testing,c++11,Unit Testing,C++11,我想编写单元测试来测试我正在编写的一些类的移动/复制构造函数/赋值。我想确保资源得到了适当的处理,当我希望调用move-ctor而不是copy-ctor时,就会调用move-ctor,反之亦然 问题是我不想为了测试这个而弄乱类代码。那么,有没有办法从类外的测试代码知道何时调用了move或copy-ctors/assignment 单元测试复制/移动CTOR/分配的一般策略是什么 PD:我使用的是单元测试框架,所以请提供一个可以在Catch中实现的答案。我从未使用过Catch,因此无法提供一个工作

我想编写单元测试来测试我正在编写的一些类的移动/复制构造函数/赋值。我想确保资源得到了适当的处理,当我希望调用move-ctor而不是copy-ctor时,就会调用move-ctor,反之亦然

问题是我不想为了测试这个而弄乱类代码。那么,有没有办法从类外的测试代码知道何时调用了move或copy-ctors/assignment

单元测试复制/移动CTOR/分配的一般策略是什么


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

我从未使用过Catch,因此无法提供一个工作示例

但是,我通过在移动/复制的对象上测试类方法,使用复杂的复制/移动构造函数(例如涉及深度复制、
std::unique_ptr
等)对类进行单元测试

例如,如果我有一个类,如下所示:

// constructor
Foo::Foo(int i) : privateMember(i) {};

// some function that operates on this private member
int Foo::bar() { return privateMember + 5 };
Foo foo{};
Foo bar(std::move(foo));
Foo foo{};
Foo bar{};
bar = std::move(foo);
Foo foo{};
Foo bar(foo);
Foo foo{};
Foo bar{};
bar = foo;
我将对
bar()
方法进行测试,然后对move、copy等构造函数进行复制。您可以轻松地完成原始测试的三到四倍

我不公开成员变量。如果您这样做了,那么您可能能够使用“is same”测试函数(假设Catch支持此功能)。例如,确保深度副本创建唯一副本(即不指向原始对象)

更新

您似乎更关心调用正确的移动或复制构造函数/赋值。如果您只是想要“移动分配”或其他标识符,我不知道该建议什么

在测试复制时,我确保在单元测试中复制对象,然后调用依赖于成员变量的浅/深副本的函数。这与我测试移动时相同。在某些情况下,您可以对原始对象运行测试(例如,测试向量实例变量在移动后的大小是否为零)

我强制移动构造函数,如下所示:

// constructor
Foo::Foo(int i) : privateMember(i) {};

// some function that operates on this private member
int Foo::bar() { return privateMember + 5 };
Foo foo{};
Foo bar(std::move(foo));
Foo foo{};
Foo bar{};
bar = std::move(foo);
Foo foo{};
Foo bar(foo);
Foo foo{};
Foo bar{};
bar = foo;
我强制执行以下移动任务:

// constructor
Foo::Foo(int i) : privateMember(i) {};

// some function that operates on this private member
int Foo::bar() { return privateMember + 5 };
Foo foo{};
Foo bar(std::move(foo));
Foo foo{};
Foo bar{};
bar = std::move(foo);
Foo foo{};
Foo bar(foo);
Foo foo{};
Foo bar{};
bar = foo;
我强制复制构造函数,如下所示:

// constructor
Foo::Foo(int i) : privateMember(i) {};

// some function that operates on this private member
int Foo::bar() { return privateMember + 5 };
Foo foo{};
Foo bar(std::move(foo));
Foo foo{};
Foo bar{};
bar = std::move(foo);
Foo foo{};
Foo bar(foo);
Foo foo{};
Foo bar{};
bar = foo;
我强制执行副本分配,如下所示:

// constructor
Foo::Foo(int i) : privateMember(i) {};

// some function that operates on this private member
int Foo::bar() { return privateMember + 5 };
Foo foo{};
Foo bar(std::move(foo));
Foo foo{};
Foo bar{};
bar = std::move(foo);
Foo foo{};
Foo bar(foo);
Foo foo{};
Foo bar{};
bar = foo;

如果您真的需要它,您可以从公开枚举类字段的某个调试虚拟类继承。在调试生成中,使用适当的枚举值(MoveConstructor)填充该字段。此字段是公开的,因此您可以在复制/移动后对其进行测试。请确保在复制/移动构造函数/赋值方法中填充它。

您能提供一个您想要为其编写测试的特定类吗?@Barry我正在处理的类太复杂和特定,无法用作示例。但是stackoverflow.com充满了移动构造函数出错的例子。其中任何一种都可能是单元测试应该检测到问题的场景。因此,请给出一个示例。就目前而言,这个问题太广泛了。也许你可以出于测试的目的包装你的类,并测试包装器上调用的适当(移动或复制,视需要而定)构造函数。我实际上对测试移动和复制都感兴趣。也就是说,我确信move和copy都创建了精确的副本,它们通过了我所有的“相同”测试。我想要的是测试效率。也就是说,我想确保在我预期的情况下移动而不是复制。@becko-我已经更新了答案。我希望这会有帮助。你不是
Foo-Foo()
foobar()函数声明?