如何在对象构造之前调用EXPECT_CALL gtest宏



我有一个在初始化列表中调用模拟函数的类。我想使用EXPECT_CALL来验证模拟函数只被调用一次。问题是我不能在构造函数之前使用宏,因为它是第一个运行的函数,也不能在它之后使用宏,因为在构造函数中调用了模拟函数。

例如:ui.cpp

class UI {
public:
UI() = default;
~UI() = default;
virtual std::string get_name() {
std::string name;
std::cin >> name;
return name;
}
};

foo.cpp

class Foo {
public:
Foo(UI& ui) : m_name(ui.get_name()) {}
~Foo() = default;
};

mock_ui.hpp

class MockUI : public UI {
MockUI() : UI() = default;
~MockUI() = default;
MOCK_METHOD(std::string, get_name, (), (override));
};

问题出现在这里:foo_test.cpp

class FooTest : ::testing::Test {
public:
// I want to call EXPECT_CALL(m_ui, get_name()) before this line executes.
FooTest() : m_foo(MockUI()) {}
~FooTest() = default;
protected:
void SetUp() override {}
void TearDown() override {}
Foo m_foo;
MockUI m_ui;
};

我尝试在SetUp()函数中初始化Foo对象,但Foo没有默认构造函数,因此必须在FooTest构造函数中初始化。

解决方案?我唯一的想法是在MockUI构造函数中像这样调用EXPECT_CALL():mock_ui.hpp

class MockUI : public UI {
MockUI() : UI() {
EXPECT_CALL(*this, get_name());
}
~MockUI() = default;

MOCK_METHOD(std::string, get_name, (), (override);
};

问题是我可能使用MockUI而不调用get_name()或多次调用它,但这是我拥有的最佳解决方案。

还有其他建议吗?

可以使用指针延迟Foo的初始化:

class FooTest : ::testing::Test {
public:
FooTest() 
{ 
EXPECT_CALL(m_ui, get_name()); 
m_foo = std::make_unique<Foo>(m_ui); 
}
protected:
std::unique_ptr<Foo> m_foo;
MockUI m_ui;
};

或者通过添加父类来首先初始化MockUI:

class FooTestHelper: public ::testing::Test
{
public:
FooTestHelper() { EXPECT_CALL(m_ui, get_name()); }
protected:
MockUI m_ui;
};
class FooTest : public FooTestHelper
{
public:
FooTest(): FooTestHelper{}, m_foo{m_ui} {}
private:
Foo m_foo;
};

您还可以在初始化虚拟变量时添加EXPECT_CALL:

class FooTest : ::testing::Test {
public:
FooTest() {}
~FooTest() = default;
protected:
void SetUp() override {}
void TearDown() override {}
MockUI m_ui;
bool dummy = (EXPECT_CALL(m_ui, get_name()), true);
Foo m_foo{m_ui};
};

我移动了m_foo的初始化,但是为了更好地看到初始化的顺序,你可以把它留在构造函数中。

相关内容

  • 没有找到相关文章

最新更新