Я разрабатываю код, использующий boost::asio
. Чтобы проверить это, мне нужно смоделировать набор классов из этой библиотеки. Я использую Google Mock, который позволяет издеваться над виртуальными методами. Обычный (и утомительный)процесс заключался бы в написании интерфейса для каждого из классов, которые мне нужно использовать.
С другой стороны, Google Mock Cookbook описывает альтернативу, когда речь идет об имитации не-виртуальных методов:с использованием шаблонов. Проблема в моем случае заключается в том, что мне может понадобиться имитировать несколько классов одновременно (, поэтому прямое использование шаблонов не сработает). Вот я и подумал:, почему бы не использовать два-уровня шаблонов? Я придумал следующее решение:
// Classes to be mocked.
class RealA
{
public:
void a() { cout << "RealA::a()" << endl; };
};
class RealB
{
public:
void b() { cout << "RealB::b()" << endl; };
};
// Mock classes.
class MockA
{
public:
void a() { cout << "MockA::a()" << endl; };
};
class MockB
{
public:
void b() { cout << "MockB::b()" << endl; };
};
template<class ABFactory>
class Program
{
public:
void setFactory(ABFactory* factory) { factory = factory; }
void useA() { typename ABFactory::A* a = factory->createA(); a->a(); delete a; }
void useB() { typename ABFactory::B b; b.b(); }
private:
ABFactory* factory;
};
template<class ParamA, class ParamB>
class TABFactory
{
public:
typedef ParamA A;
typedef ParamB B;
A* createA() { return new A; };
B* createB() { return new B; };
};
typedef TABFactory<RealA, RealB> RealABFactory;
typedef TABFactory<MockA, MockB> MockABFactory;
Тогда нормальным использованием будет:
Program<RealABFactory> p;
p.useA();
p.useB();
В то время как тест будет:
Program<MockABFactory> t;
t.useA();
t.useB();
Это начинает усложняться, когда фиктивные классы имеют методы со сложными параметрами (, такие как другие классы из та же самая библиотека, которая не может быть имитирована). В целом, кажется, что это не масштабируется. Любые мысли об этом решении или предложения по другим подходам к проблеме?