Jir*_*Jir 28 c++ unit-testing private-members private-methods
我对单元测试很新,我有点困惑.
我试图在一个名为C++的类上进行单元测试(使用Boost单元测试框架)VariableImpl
.这是详细信息.
class Variable
{
public:
void UpdateStatistics (void) {
// compute mean based on m_val and update m_mean;
OtherClass::SendData (m_mean);
m_val.clear ();
}
virtual void RecordData (double) = 0;
protected:
std::vector<double> m_val;
private:
double m_mean;
};
class VariableImpl : public Variable
{
public:
virtual void RecordData (double d) {
// put data in m_val
}
};
Run Code Online (Sandbox Code Playgroud)
我的问题是如何检查均值是否正确计算?注意1)m_mean
受保护,2)UpdateStatistics
调用另一个类的方法,然后清除向量.
我能看到的唯一方法是添加一个getter(例如GetMean
),但我根本不喜欢这个解决方案,也不认为它是最优雅的.
我应该怎么做?
如果我要测试私有方法而不是私有变量,我该怎么办?
TIA,
JIR
Kon*_*lph 49
那么,单元测试应该测试单元,理想情况下每个类都是一个独立的单元 - 这直接来自单一责任原则.
因此,测试一个类的私有成员不是必需的 - 该类是一个黑盒子,可以在单元测试中按原样覆盖.
另一方面,这并不总是正确的,有时有充分的理由(例如,类的几个方法可能依赖于应该测试的私有效用函数).一个非常简单,非常苛刻但最终成功的解决方案是在包含定义类的标题之前将以下内容放入单元测试文件中:
#define private public
Run Code Online (Sandbox Code Playgroud)
当然,这会破坏封装并且是邪恶的.但是为了测试,它有助于实现目的.
Dum*_*der 11
对于受保护的方法/变量,从类继承Test类并进行测试.
对于私人,介绍一个朋友类.它不是最好的解决方案,但可以为您完成工作.
或者这个黑客
#define private public
Run Code Online (Sandbox Code Playgroud)
总的来说,我同意其他人在这里所说的话 - 只有公共接口应该进行单元测试.不过,我刚才有一个案例,我必须首先调用受保护的方法,为特定的测试用例做准备.我首先尝试了#define protected public
上面提到的方法; 这适用于Linux/gcc,但在Windows/VisualStudio中失败了.原因是更改protected
为public
也改变了受损的符号名称,因此给了我链接器错误:库提供了一个受保护的 __declspec(dllexport) void Foo::bar()
方法,但是#define
在适当的位置,我的测试程序期望一个公共 __declspec(dllimport) void Foo::bar()
方法,它给了我一个未解决的符号错误.
出于这个原因,我切换到一个friend
基于解决方案,在我的类标题中执行以下操作:
// This goes in Foo.h
namespace unit_test { // Name this anything you like
struct FooTester; // Forward declaration for befriending
}
// Class to be tested
class Foo
{
...
private:
bool somePrivateMethod(int bar);
// Unit test access
friend struct ::unit_test::FooTester;
};
Run Code Online (Sandbox Code Playgroud)
在我的实际测试案例中,我这样做了:
#include <Foo.h>
#include <boost/test/unit_test.hpp>
namespace unit_test {
// Static wrappers for private/protected methods
struct FooTester
{
static bool somePrivateMethod(Foo& foo, int bar)
{
return foo.somePrivateMethod(bar);
}
};
}
BOOST_AUTO_TEST_SUITE(FooTest);
BOOST_AUTO_TEST_CASE(TestSomePrivateMethod)
{
// Just a silly example
Foo foo;
BOOST_CHECK_EQUAL(unit_test::FooTester::somePrivateMethod(foo, 42), true);
}
BOOST_AUTO_TEST_SUITE_END();
Run Code Online (Sandbox Code Playgroud)
这适用于Linux/gcc以及Windows/VisualStudio.
归档时间: |
|
查看次数: |
27075 次 |
最近记录: |