【问题标题】:Using googlemock EXPECT_CALL with shared_ptr?将 googlemock EXPECT_CALL 与 shared_ptr 一起使用?
【发布时间】:2012-04-26 21:34:47
【问题描述】:

我有一个测试可以很好地使用原始指针,但我无法让它与std::shared_ptr 一起使用。类是这样的:

class MyClass
{
    MyClass(SomeService *service);
    void DoIt();
}

我的测试代码是这样的:

    class MyClassTests : public ::testing::Test
    {
    public:
        MyClassTests():
            myClass_(new MyClass(&service_))
        {}

    protected:
        SomeServiceFake service_;
        MyClassSharedPointer myClass_;
    };

TEST_F(MyClassTests, DoIt_DoesNotMeetCriteria_DoesNotPerformAction) {

    // Arrange
    EXPECT_CALL(service_, MeetsCriteria(_))
        .WillRepeatedly(Return(false));

    EXPECT_CALL(service_, PerformAction(_))
        .Times(0);

    // Act
    myClass_->DoIt();
}

在这个测试中,service_ 是在测试中在堆栈上创建的 mock/fake,我将地址传递给MyClass 的构造函数。将MyClass 更改为service 作为shared_ptr,我的新课程如下所示:

class MyClass
{
    MyClass(std::shared_ptr<SomeService> service);
    DoIt();
}

我在测试中尝试的是:

    class MyClassTests : public ::testing::Test
    {
    public:
        MyClassTests():
            myClass_(new MyClass(std::shared_ptr<SomeService>(&service_)))
        {

        }
            ...

但是,当我这样做时,测试失败并显示:

Debug Assertion Failed!
Expression: _CtrlIsValidHeapPointer(pUserData)

简而言之,我需要一个shared_ptrservice_(这是一个假对象)来传递给MyClass 构造函数,并且我需要一个EXPECT_CALL 函数的非指针。我怎样才能让它正常工作?

更新

尝试动态分配 SomeServiceFake 以获取 shared_ptr,然后在 service_ 上使用 * 运算符,这让我“更进一步”,但现在我收到以下错误:

error : this mock object
(used in test MyClassTests.DoIt_DoesNotMeetCriteria_DoesNotPerformAction)
should be deleted but never is. Its address is @009BBA68.
1>EXEC : error : 1 leaked mock object found at program exit.

更新 2

使用Mock::AllowLeak(service_.get());,所以我现在可以解决这个问题。希望我能得到答案。

【问题讨论】:

    标签: c++ shared-ptr googlemock


    【解决方案1】:

    更像这样定义你的测试类:

    class MyClassTests : public ::testing::Test {
     public:
      MyClassTests():
          service_(new SomeServiceFake), myClass_(new MyClass(service_)) {}
     protected:
      std::shared_ptr<SomeServiceFake> service_;
      std::shared_ptr<MyClass> myClass_;
    };
    

    和你的测试:

      EXPECT_CALL(*service_, MeetsCriteria(_))
          .WillRepeatedly(Return(false));
    
      EXPECT_CALL(*service_, PerformAction(_))
          .Times(0);
    

    【讨论】:

    • 这是 gmock 的一个不幸的缺点——它真的不能很好地与智能指针配合使用。我猜你的实际代码比你在这里发布的要复杂一些? gmock 可以通过几种方式对智能指针管理的泄漏对象给出误报(例如,参见here)。如果没有实际代码,很难说明 gmock 报告泄漏的原因。
    【解决方案2】:

    这与测试框架无关。正如您自己所说,您正在从堆栈分配的对象(即具有自动生命周期的对象)创建一个 shared_ptr 。这根本不符合逻辑。共享指针通常由new 的结果创建。如果您将自定义 Deleter 作为第二个参数传递给 shared_ptr 构造函数,您可能能够使其工作,但最好只使用 new 创建对象。

    【讨论】:

    • 这很有意义,但是如果我 new SomeServiceFake,我相信 googlemock 期望 EXPECT_CALL 的类对象,我该如何实现呢?
    • 用户:也许说 *service_ 来获取引用并将其传递给 EXPECT_CALL? @VJovic:我不明白你的评论。
    猜你喜欢
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 2013-08-24
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 2018-05-13
    相关资源
    最近更新 更多