Bil*_*eal 1 c++ tdd unit-testing
请考虑以下内容(我很抱歉代码量;但这是我能想到的最小例子......):
class SomeDataThingy
{
};
struct IFileSystemProvider
{
virtual ~IFileSystemProvider() {}
//OS pure virtual methods
}
struct DirectFileSystemProvider
{
//Simply redirects the pure virtuals from IFileSystemProvider to OS functions.
}
struct SomeDataBlock
{
//Stored inside SomeDataThingy; contains specific data
SomeDataBlock(const SomeDataThingy& subject, const IFileSystemProvider& os = DirectFileSystemProvider())
{
//Calculate some data from the Operating System based upon a filename stored in SomeDataThingy.
}
};
struct IFilter
{
virtual ~IFilter() {}
virtual int Matches(const SomeDataThingy&) const = 0;
virtual void Calculate(SomeDataThingy&) const = 0;
};
class SomeFilter : public IFilter
{
int Matches(const SomeDataThingy& subject) const
{
if (!Subject.Contains<SomeDataBlock>())
return UNKNOWN;
else
return /* This filter matches */
}
void Calculate(SomeDataThingy& subject) const
{
std::auto_ptr<SomeDataBlock> data(new SomeDataBlock(subject));
subject.Install<SomeDataBlock>(data);
}
};
Run Code Online (Sandbox Code Playgroud)
我想SomeFilter::calculate在这里测试一下.问题是SomeDataBlock的构造函数调用文件系统.SomeDataBlock本身由mock进行测试IFileSystemProvider.但是,我没有一种简单的方法来注入模拟SomeFilter::Calculate; 并且不幸的是我无法更改IFilter接口以允许将mock作为参数传递给Calculate,因为还有其他过滤器,这样的模拟没有任何意义.
我怎么测试Calculate?
你能修改SomeFilter的构造函数吗?如果是这样,你可以这样注入IFileSystemProvider.
class SomeFilter : public IFilter
{
public:
SomeFilter(const IFileSystemProvider& fs = DirectFileSystemProvider())
: fs(fs)
{
}
private:
int Matches(const SomeDataThingy& subject) const
{
if (!Subject.Contains<SomeDataBlock>())
return UNKNOWN;
else
return /* This filter matches */
}
void Calculate(SomeDataThingy& subject) const
{
std::auto_ptr<SomeDataBlock> data(new SomeDataBlock(subject, fs));
subject.Install<SomeDataBlock>(data);
}
IFileSystemProvider fs;
};
Run Code Online (Sandbox Code Playgroud)
您还可以在SomeFilter上创建一个公共成员,以允许用户在调用Calculate之前提供IFileSystemProvider,但是在构造对象之后.