【问题标题】:Confused about testing an interface implementing method in C++.. how can I test this?对在 C++ 中测试接口实现方法感到困惑。我该如何测试呢?
【发布时间】:2010-08-27 15:04:11
【问题描述】:

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

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

【问题讨论】:

  • 你能继承SomeDataThingy 并使用它吗?
  • @the-alchemist:Calculate 怎么知道此时要实例化哪个SomeDataThingy

标签: c++ unit-testing tdd


【解决方案1】:

可以修改 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。

【讨论】:

  • 我认为修改构造函数是要走的路。
  • 这是一种只会给你耳光的解决方案,让你想知道......为什么我没有想到呢? :P
  • @Billy:不要感觉太糟糕。当我遇到一个非常相似(尽管略有不同)的问题的解决方案时,我有完全相同的感觉。我的问题涉及复合设计模式,以及如何在不污染抽象接口的情况下自定义对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-21
  • 2020-12-09
  • 1970-01-01
相关资源
最近更新 更多