我是gtest / gmock的新手并尝试在c ++中测试一个简单的函数,该函数有两个指针'm_propBsh_p'和'm_eBsh_p';在一些工厂创建之后,这些指针变得有效,但是我不想涉及工厂类的复杂性和回调。 以下是我想为其编写测试的函数定义:
std::string Foo::toString(const std::string &indent) const
{
....
std::string str =
(m_propBsh_p != nullptr) ? m_propBsh_p -> toString("P-BSH: ") : "-";
str +=
(m_eBsh_p != nullptr) ? m_eBsh_p -> toString("E-BSH: ") : "-";
return str;
}
因为我只是想测试这个特定的toString函数,所以我只想拥有'm_propBsh_p'和'm_eBsh_p'的有效指针。我正在瞄准/尝试以下内容:
//Assuming to have mocked class for pointers
std::shared_ptr<MockedBshClass> m_mockEBsh_p;
std::shared_ptr<MockedBshClass> m_mockPropBsh_p;
TEST_F(FooTest, toStringBshInfoPass)
{
std::string eBshAndpBshStr = "eBshAndpBshStr";
ON_CALL(*m_mockPropBsh_p, toString(_)).WillByDefault(Return(eBshAndpBshStr));
ON_CALL(*m_mockEBsh_p, toString(_)).WillByDefault(Return(eBshAndpBshStr ));
//EXPECT_CALL((*m_mockPropBsh_p), toString(_)).Times(1);
//EXPECT_CALL((*m_mockEBsh_p), toString(_)).Times(1);
//Call mock or some fake function which makes m_propBsh_p & m_eBsh_p valid.
foo->makePtrValidAgain(); //however this is a complex function which bring more callbacks and complexity and i do not want to call, instead i want to have some fake/mocked function which just gives me valid pointers
EXPECT_THAT(foo->toString(""),HasSubstr(eBshAndpBshStr+eBshAndpBshStr));
}
以下是Foo类和指针的位背景:
Class Foo : fooParent..
{
...
void makePtrValidAgain();
std::string toString();
..
typedef std::shared_ptr<BshClass> m_propBsh_p;
typedef std::shared_ptr<BshClass> m_eBsh_p;
...
};
void Foo::makePtrValidAgain()
{
...
auto someFactory = m_dependencyContainer->get<bssh::SomeFactory>();
assert(someFactory);
auto nextTask = [this](std::uint32_t dummy){runAfterFoo();};
m_propBsh_p = someFactory->create(callback, nextTask);
m_propBsh_p->execute();
...
//and same happens with m_eBsh_p
return;
}
我不确定,使用gmock / gtest避免测试这种简单函数的复杂性的最佳方法是什么,对我来说就是拥有如上所述的有效指针。
答案 0 :(得分:1)
首先,您的ON_CALL
似乎不正确。您嘲笑BshClass
,因此您希望对BshClass
的方法创建期望(并且toString()
不是一个)。你应该模拟一下
ON_CALL(*m_mockEBsh_p, execute())/*stuff to do*/;
回答你的问题:
m_propBsh_p
和m_eBsh_p
),那么您可以使用std::shared_ptr
功能来控制它们是否指向某些内容与否(例如通过reset()
)。makePtrValidAgain()
中提取工厂方法似乎是个好主意 - 这个函数已经有多个职责,它会在它们上创建指针和调用方法。我建议像:
Class Foo : fooParent..
{
...
void makePtrValidAgain();
std::string toString();
..
private:
void resetPointers();
typedef std::shared_ptr<BshClass> m_propBsh_p;
typedef std::shared_ptr<BshClass> m_eBsh_p;
...
};
void Foo::makePtrValidAgain()
{
...
resetPointers(); //if needed
m_propBsh_p->execute();
...
//and same happens with m_eBsh_p
}
void resetPointers()
{
auto someFactory = m_dependencyContainer->get<bssh::SomeFactory>();
assert(someFactory);
auto nextTask = [this](std::uint32_t dummy){runAfterFoo();};
m_propBsh_p = someFactory->create(callback, nextTask);
//also with the other pointer
//or better pass the pointer to reset as argument if possible
}
并尽可能在Foo构造函数中调用resetPointers()
。或者公开并从UT调用它。这样,问题就会落到第一个选项,m_propBsh_p
和m_eBsh_p
被设置,你可以通过模拟指针从UT访问它们。