【问题标题】:C++ Gmock - test function which uses shared_ptr <FactoryClass>C++ Gmock - 使用 shared_ptr <FactoryClass> 的测试函数
【发布时间】:2018-02-24 19:46:42
【问题描述】:

我是 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】:

    首先,您的ON_CALLs 似乎不正确。您模拟了BshClass,因此您希望对BshClass 的方法产生期望(而toString() 不是其中之一)。例如,您应该模拟

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

    回答你的问题:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-05
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      相关资源
      最近更新 更多