Skip to content

Latest commit

 

History

History
174 lines (132 loc) · 3.92 KB

281.md

File metadata and controls

174 lines (132 loc) · 3.92 KB
Info

Example

#include <gmock/gmock.h>

struct mock {
  MOCK_METHOD(void, on, (int));
};

int main() {
  StrictMock<mock> mock{};
  EXPECT_CALL(mock, on(42));
  mock.on(43); // failure : Unexpected mock function call
}

https://godbolt.org/z/s1dvcj4Td

Puzzle

template<class... TEvents>
struct mock_on; // TODO

template<class T>
class foo {
  public:
    explicit(true) foo(const T& t) : t_{t} { }

    auto run(const auto& event) const -> void {
        t_.on(event);
    }

  private:
    const T& t_;
};

int main() {
    struct event1 { constexpr auto operator<=>(const event1&) const = default; } event1;
    struct event2 { constexpr auto operator<=>(const event2&) const = default; } event2;
    struct event3 { constexpr auto operator<=>(const event3&) const = default; } event3;

    "mock single event"_test = [&] {
        mock_on<decltype(event1)> mock{};
        foo foo{mock};

        EXPECT_CALL(mock, on(event1));

        foo.run(event1);
    };

    "mock mutliple events"_test = [&] {
        mock_on<decltype(event1), decltype(event2), decltype(event3)> mock{};
        foo foo{mock};

        EXPECT_CALL(mock, on(event1));
        EXPECT_CALL(mock, on(event2));
        EXPECT_CALL(mock, on(event3));

        foo.run(event1);
        foo.run(event2);
        foo.run(event3);
    };
}

https://godbolt.org/z/9d5Gq1M7x

Solutions

template<typename TEvent>
struct mock_on_impl
{
    MOCK_METHOD(void, on, (TEvent), (const));
};

template<typename...TEvents>
struct mock_on : mock_on_impl<TEvents>...
{
    using mock_on_impl<TEvents>::gmock_on...;
    using mock_on_impl<TEvents>::on...;
};

https://godbolt.org/z/551zWc1xW

template <class TEvent>
struct mock_on_impl {
    MOCK_METHOD(void, on, (TEvent), (const));
};

}  // namespace detail

template <class... TEvents>
struct mock_on : testing::StrictMock<detail::mock_on_impl<TEvents>>... {
    using detail::mock_on_impl<TEvents>::on...;
    using detail::mock_on_impl<TEvents>::gmock_on...;
};

https://godbolt.org/z/16ex6b9hn

namespace detail {
  template <class TEvent>
  struct mock {
    MOCK_METHOD(void, on, (const TEvent&), (const));
  };
}

template <class... TEvents>
struct mock_on : ::testing::StrictMock<detail::mock<TEvents>>... {
  using ::testing::StrictMock<detail::mock<TEvents>>::on...;
  using ::testing::StrictMock<detail::mock<TEvents>>::gmock_on...;
};

https://godbolt.org/z/EerzEKM48

template <class TEvent>
struct on_impl {
    MOCK_METHOD(void, on, (const TEvent&), (const));
};

template <class... TEvents>
struct mock_on : testing::StrictMock<on_impl<TEvents>>... {
    using testing::StrictMock<on_impl<TEvents>>::on...;
    using testing::StrictMock<on_impl<TEvents>>::gmock_on...;
};

https://godbolt.org/z/1vqeY4nGf

template<int N> struct None{};

template<class TEvent1, class TEvent2 = None<0> , class TEvent3 = None<1> >
struct mock_on {
    MOCK_METHOD(void, on, (TEvent1), (const));
    MOCK_METHOD(void, on, (TEvent2), (const));
    MOCK_METHOD(void, on, (TEvent3), (const));
};

https://godbolt.org/z/n557c9oP3

template<class TEvent>
struct mock{
    MOCK_METHOD(void, on, (const TEvent&), (const));
};

template<class... TEvents>
struct mock_on : ::testing::StrictMock<mock<TEvents>>...{
    using ::testing::StrictMock<mock<TEvents>>::on...;
    using ::testing::StrictMock<mock<TEvents>>::gmock_on...;
};

https://godbolt.org/z/MnasrTYrh