0

让我们假设下面的 C 类非常慢,并且我不想在我的单元测试中使用它。所以我创建了一个 MockC,它最终将实现与 C 类相同的接口。

class IC
{
public:
    virtual std::string getName() = 0;
};

class C: public IC
{
public:
    C(){}
    C(int c) : _c(c){}
    int _c;
    virtual std::string getName()
    {
        // do really slow stuff with an external library
        ...
    }
};

class MockC: public IC
{
public:
    MockC(){}
    MockC(int c) : _c(c){}
    int _c;
    virtual std::string getName()
    {
       ...
    }
};

我还有一个精简的输入迭代器,它在取消引用时创建一个 Value 类型的对象(可以是 C 或 MockC):

template<class Value>
class GetNextIterator 
{
public:
    typedef int (*GetNext)();

    GetNextIterator(GetNext getNext): _getNext(getNext)
    {
        _current = _getNext();
    }

    const Value* operator->() const
    {
        return new Value(_current);
    }

protected:
    int _current;
    GetNext _getNext;
};

int count = 0;
int getNext()
{
    return count++;
}

然后我有另一个类也很慢,它是 C 类对象的父类,但也有自己的属性,如下所示:

class ID
{
public:
    virtual std::string getName() = 0;
};

class D: public ID
{
public:
    typedef GetNextIterator<C> Iterator;

    virtual ChildIterator begin() const
    {
        return Iterator(getNext);
    }

    virtual std::string getName()
    {
        // again really slow and accessing external dependencies
        ...
    }
};

现在我该如何测试以下功能,例如:

int f(D* d)
{
    D::ChildIterator i = d->begin();
    if (d.getName() == "something or other")  
        return i->_c;
    else
        return 1;
}

请记住,我不希望使用具体的类 C 或 D。我应该怎么做才能对 f() 和类似函数进行完全单元测试?我完全愿意重新设计上面的任何代码以使其与单元测试一起使用。

4

1 回答 1

1

只模拟你需要模拟的东西。为了测试f()的行为,你在正确的轨道上模拟出沉重的 C 对象。您确实必须编写足够的测试用例来涵盖您认为f()需要处理的任何行为。但是您不需要模拟 Container 本身,这应该很容易测试。所以,摆脱 IContainer 的概念。

但是,您确实需要修改 Container 以便它接受 IC ​​对象而不是具体对象的输入(您也不需要它是基于模板的,如果只是为了测试, Container 可以保存 literal IC*)。测试代码和生产代码都将为f(). 测试代码将首先用 MockC 对象填充一个 Container,而生产代码将在调用f().

于 2012-06-26T21:57:53.493 回答