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

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

Mer*_*ham 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;
};
Run Code Online (Sandbox Code Playgroud)

您还可以在SomeFilter上创建一个公共成员,以允许用户在调用Calculate之前提供IFileSystemProvider,但是在构造对象之后.