c++ 用Gmock模拟重载方法

o7jaxewo  于 2023-05-08  发布在  其他
关注(0)|答案(1)|浏览(229)

问候,所以我有一个界面如下

class AInterface {
public:
    /// The different states the =A can be in
    enum class State {
        IDLE,
        BUSY
    };

    
    struct AMetadata {
    /**
     * Default constructor
     */
    AMetadata() = default;

    AMetadata(State state)
    : state(state){}

    State state = State::IDLE;
    };

    /// Destructor.
    virtual ~AInterface() = default;

    virtual void onStateChanged(State state){}; // deprecated but still have to be here
    virtual void onStateChanged(const AMetadata& metadata){}; // i am adding this method
};

我的模拟类是这样定义的

class MockObserver : public AInterface {
public:
    MOCK_METHOD1(onStateChanged, void(State state));
    MOCK_METHOD1(onStateChanged, void(const AMetadata& metadata));
};

// arg is passed to the matcher implicitly
// arg is the actual argument that the function was called with
MATCHER_P(AMetadataMatcher, expectedMetadata, "") {
    return arg.state == expectedMetadata.state;
}

基本上在测试代码中,实现看起来像这样,其中以前的参数是State,但现在的参数必须是AMetadata

EXPECT_CALL(*m_mockObserver, onStateChanged(_)).Times(AnyNumber());

EXPECT_CALL(*m_mockObserver, onStateChanged(AInterface::State::BUSY))
            .WillOnce(Invoke([&](AMetadata metadata) {
                EXPECT_EQ(...,...);
            }));
EXPECT_CALL(*m_mockObserver, onStateChanged(AInterface::State::IDLE))
            .WillOnce(Invoke([&](AMetadata metadata) {
                EXPECT_EQ(...,...);
            }));

编译是显然我得到编译错误

ATest.cpp:: error: call to member function 'gmock_onStateChanged' is ambiguous
    EXPECT_CALL(*m_mockObserver, onStateChanged(_).Times(AnyNumber()));

我尝试了::testing::TypedEq和::testing::An,就像下面一样,我仍然得到编译错误

EXPECT_CALL(*m_mockObserver, onStateChanged(::testing::TypedEq<const AMetadata&>(_))).Times(AnyNumber());

ATest.cpp:1288:49:错误:没有匹配的函数用于调用'TypedEq' EXPECT_CALL(*m_mockObserver,onStateChanged(::testing::TypedEq<const AMetadata&>()).Times(Anynumber());
我甚至尝试了自定义匹配器的东西一样

AMetadata metadata;
metadata.state = IDLE;
EXPECT_CALL(*m_mockObserver, onStateChanged(AMatcher<const AMetadata&>(metadata)).Times(AnyNumber()));

但我仍然得到错误,所以我不知道什么是最好的方式来工作与重载的功能在gmock,基本上我需要写调用的地方期待调用需要工作的值在一个结构体和我在一个情况下,不仅重载方法有相同的名称,但相同数量的论点,以及,任何指导或代码片段将不胜感激.

pbwdgjma

pbwdgjma1#

你可以在Google测试文档中使用这个解决方案

在重载函数之间选择

如果你期望调用一个重载的函数,编译器可能需要一些关于它是哪个重载版本的帮助。
若要消除在此对象的常量上重载的函数的歧义,请使用Const()参数 Package 器。使用::testing::ReturnRef;

class MockFoo : public Foo {
  ...
  MOCK_METHOD(Bar&, GetBar, (), (override));
  MOCK_METHOD(const Bar&, GetBar, (), (const, override));
};

...
  MockFoo foo;
  Bar bar1, bar2;
  EXPECT_CALL(foo, GetBar())         // The non-const GetBar().
      .WillOnce(ReturnRef(bar1));
  EXPECT_CALL(Const(foo), GetBar())  // The const GetBar().
      .WillOnce(ReturnRef(bar2));

(Const()由gMock定义,并返回对其参数的const引用。
要消除具有相同数量参数但不同参数类型的重载函数的歧义,您可能需要指定匹配器的确切类型,可以通过将匹配器 Package 在Matcher()中,或者使用类型固定的匹配器(TypedEq,An()等):

using ::testing::An;
using ::testing::Matcher;
using ::testing::TypedEq;

class MockPrinter : public Printer {
 public:
  MOCK_METHOD(void, Print, (int n), (override));
  MOCK_METHOD(void, Print, (char c), (override));
};

TEST(PrinterTest, Print) {
  MockPrinter printer;

  EXPECT_CALL(printer, Print(An<int>()));            // void Print(int);
  EXPECT_CALL(printer, Print(Matcher<int>(Lt(5))));  // void Print(int);
  EXPECT_CALL(printer, Print(TypedEq<char>('a')));   // void Print(char);

  printer.Print(3);
  printer.Print(6);
  printer.Print('a');
}

我希望这能有所帮助

相关问题