请考虑以下内容(我很抱歉代码数量;但这是我能想到的最小例子......):
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);
}
};
我想在这里测试SomeFilter::calculate
。问题是SomeDataBlock的构造函数调用文件系统。 SomeDataBlock本身由模拟IFileSystemProvider
测试。但是,我没有一种简单的方法将模拟注入SomeFilter::Calculate
;并且不幸的是我无法更改IFilter
接口以允许模拟作为参数传递给Calculate
,因为还有其他过滤器,这样的模拟没有任何意义。
如何测试Calculate
?
答案 0 :(得分:5)
你能修改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;
};
您还可以在SomeFilter上创建一个公共成员,以允许用户在调用Calculate之前提供IFileSystemProvider,但是在构造对象之后。