Почему мое ожидание Hippomock не выполняется при использовании множественного наследования - PullRequest
1 голос
/ 04 октября 2019

Я использую Hippomocks и у меня есть класс, который реализует универсальный интерфейс. Когда я возлагаю ожидания на этот класс, я не получаю ожидаемого поведения.

Это мой минимальный "рабочий" пример

template <class T>
struct Foo {
  virtual ~Foo() = default;
  virtual void bar(const T& t) = 0;
};

struct Baz : public Foo<int>, public Foo<double> {
  void bar(const int& t) override = 0;
  void bar(const double& t) override = 0;
};

TEST_CASE("Foo")
{
  MockRepository mocks;

  auto baz = mocks.Mock<Baz>();

  mocks.ExpectCall(baz, Foo<int>::bar);
  baz->bar(12);

  mocks.ExpectCall(baz, Foo<double>::bar);
  baz->bar(234.3);
}

Я ожидаю, что этот тест пройдет без проблем. Однако тест завершается неудачно со следующим сообщением (слегка отредактировано для удаления имен проектов):

test_foo.cpp|28| FAILED:
|| due to unexpected exception with message:
||   Function called without expectation!
||   Expectations set:
||   test_foo.cpp(31)
||   : Expectation for Foo<int>::bar(...) on the mock at 0x0x5569df8f3400 was
||   satisfied.
||   test_foo.cpp(34)
||   : Expectation for Foo<double>::bar(...) on the mock at 0x0x5569df8f3400 was
||   not satisfied.
I am expecting the bar() belonging to Foo<double> to be invoked.

Ответы [ 2 ]

1 голос
/ 04 октября 2019

Мне было любопытно, как можно реализовать Mock без определения всех методов вручную (как это делают другие библиотеки-насмешки), но оказывается, что это не работает. Реализация Mock использует Undefined Behavior, потому что это просто reinterpret_cast несвязанный класс с Baz:

template <typename base>
base *MockRepository::Mock() {
    mock<base> *m = new mock<base>(this);
        mocks.push_back(m);
    return reinterpret_cast<base *>(m);
}

Он выполняет различные другие глупые вещи, такие как возня с vtable. Ничто из этого не может работать надежно.

0 голосов
/ 04 октября 2019

Hippomocks заботится о случае, когда есть перегруженные функции класса.

Ожидания, которые я должен был использовать, следующие:

  mocks.ExpectCallOverload(baz, static_cast<void (Baz::*)(const int&)>(&Baz::bar));
  baz->bar(12);

  mocks.ExpectCallOverload(baz, static_cast<void (Baz::*)(const double&)>(&Baz::bar));
  baz->bar(234.3);

Синтаксис ужасен, но теперь он ведет себякак и ожидалось.

У меня должен быть RTFM ...

...