Дразнить чисто виртуальные методы, если у класса также есть не виртуальные методы? - PullRequest
1 голос
/ 28 мая 2011

В настоящее время я использую HippoMocks в качестве среды для моделирования и не могу понять, как смоделировать чисто виртуальный метод MockMe() в приведенном ниже коде. Я не хочу издеваться над любым из не виртуальных методов (что, вероятно, даже невозможно), вместо этого я хочу, чтобы они сделали то, для чего они предназначены, и назвали виртуальный имитированный.

struct A
{
  void Run() { RunImpl(); }
  virtual void RunImpl() = 0;
};

struct B : public A
{
    //implement A::RunImpl
  void RunImpl() { MockMe(); }

    //this one I want to mock
  virtual void MockMe() = 0;
};

MockRepository mocks;
B* b = mocks.InterfaceMock< B >();
mocks.OnCall( b, B::MockMe );
b->Run(); //throws NotImplementedException for Run()

Есть ли способ заставить это работать с HippoMocks? Или с другой рамкой? Или с некоторыми модификациями исходного кода?

Ответы [ 2 ]

0 голосов
/ 26 июня 2011

update / answer: я нашел способ обойти это, извлекая новый класс из B и добавляя помощника для переадресации вызовов на соответствующий метод. Кроме того, также важно использовать ClassMock вместо InterfaceMock.

Итак, используя приведенный выше пример, это работает:

struct MockHelper : public B
{
  void InvokeRunImpl()
  {
    B::RunImpl();
  }

  virtual void MockMe()
  {
    //never called, but must be defined so MockHelper can be instantiated
  }
};

MockHelper* b = mocks.ClassMock< MockHelper >();
auto invokeIt = [b]() { b->InvokeRunImpl(); };
mocks.OnCall( b, MockHelper::RunImpl ).Do( invokeIt );
mocks.OnCall( b, MockHelper::MockMe );
//ok now: calls A::Run, which calls mocked RunImpl, which in turn
//calls InvokeRunImpl, which in turn calls B::RunImpl
b->Run();
0 голосов
/ 28 мая 2011

Я не использовал фальшивые фреймворки, но это должно быть одной из самых простых вещей ...

Расширить класс B классом Mock, где вы переопределяете тольковиртуальные методы и форвард на конструкторы.Затем создайте экземпляр производного класса и передайте его в качестве ссылки / указателя на mocked-класс, который, вероятно, готов обработать остальная часть приложения: если класс имеет чисто виртуальные функции, то приложение использует его полиморфно через указателии / или ссылки.

...