C ++ Gmock - 使用shared_ptr的测试函数

问题描述 投票:0回答:1

我是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避免测试这种简单函数的复杂性的最佳方法是什么,对我来说,目的是拥有如上所述的有效指针。

c++ factory factory-pattern googlemock gmock
1个回答
1
投票

首先,看来你的ON_CALLs是不正确的。你嘲笑BshClass,所以你想创造对BshClass方法的期望(并且toString()不是一个)。你应该举个例子

ON_CALL(*m_mockEBsh_p, execute())/*stuff to do*/;

回答你的问题:

  1. 如果工厂已经在Foo构造函数中使用(你将模拟指针传递给m_propBsh_pm_eBsh_p),那么你可以使用std::shared_ptr功能来控制它们是否指向某些东西(例如通过reset())。
  2. 否则,从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_pm_eBsh_p被设置,你可以通过模拟指针从UT访问它们。

© www.soinside.com 2019 - 2024. All rights reserved.