让我假装下面的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()和类似的函数?我完全愿意重新设计上面的任何代码,以便使用单元测试。
答案 0 :(得分:1)
只模拟你需要模拟的东西。为了测试f()
的行为,您可以通过模拟重C对象来走上正确的轨道。您必须编写足够的测试用例来涵盖您认为f()
需要处理的任何行为。但是你不需要模拟容器本身,这应该是容易测试的。所以,摆脱IContainer概念。
但是,你需要修改Container,使其接受IC对象的输入而不是具体的对象(你也不需要这个是基于模板的,如果只是为了测试,Container可以保持文字{{1 }})。测试代码和生产代码都将为IC*
提供一个真正的Container对象。测试代码将首先使用MockC对象填充Container,而生产代码将在调用f()
之前填充带有C对象的Container。