【发布时间】:2015-03-04 12:41:16
【问题描述】:
我正在为几个类 (C++) 编写单元测试,并在尝试为复制构造函数和赋值运算符编写单元测试时遇到了问题。 两者都可能出错的一个基本问题是程序员向类中添加了一个成员,然后忘记更新 c'ctor 和/或 operator=。
我当然可以按照以下方式编写单元测试:
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);
}
很好。 现在程序员添加了一个成员c,但不更新操作符和测试用例。
class MyClass()
{
public:
float c;
// ...
}
即使操作符现在坏了,测试用例仍然会成功。
现在,我们可以执行以下操作:
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
// ...
}
我找不到任何关于如何解决这个问题的好信息,但肯定有人以前遇到过这个问题!? 是不是太明显了,我完全错过了!?
【问题讨论】:
-
要吸取的教训是,编写不需要的代码是不必要的潜在错误来源。只需删除错误的赋值运算符即可。或者提供一个实际需要的例子。
-
好吧,课程当然没那么简单。让我们假设有一个成员阻止隐式复制构造函数做正确的事情。例如,假设 MyClass 包含一个互斥体。
-
好的。然后去问开发人员为什么他们没有先写测试就添加了一个数据成员:-)
-
我打算建议实施 operator==() 但后来意识到这也会有同样的问题! :P
-
您似乎在问是否有一种机制可以编写具有超越修改有效性的单元测试。这样的条件似乎消除了对代码审查的需要,而这种分歧会被发现的地方。我不知道您在哪里工作,但在我的工作中,开发人员 负责更新受代码更新影响的单元测试。如果他们不这样做并且测试错误地或通过,那他们的头上。
标签: c++ unit-testing copy-constructor assignment-operator