对在C ++中测试接口实现方法感到困惑..如何测试?

时间:2010-08-27 15:04:11

标签: c++ unit-testing tdd

请考虑以下内容(我很抱歉代码数量;但这是我能想到的最小例子......):

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

1 个答案:

答案 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,但是在构造对象之后。