34

私はテストに GoogleMock/GoogleTest を使用しています。マッチャーがパラメーターとしてモックへの shared_ptr を持ち、同じ shared_ptr で EXPECT が呼び出されると、奇妙な動作が見られます。問題のあるコード:

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
using namespace boost;
using namespace testing;

struct MyParameter
{
    virtual ~MyParameter() {}
    virtual void myMethod() = 0;
};

struct MyParameterMock : public MyParameter
{
    MOCK_METHOD0(myMethod, void());
};

struct MyClass
{
    virtual ~MyClass() {}
    virtual void myMethod(shared_ptr<MyParameter> p) {}
};

struct MyClassMock : public MyClass
{
    MOCK_METHOD1(myMethod, void(shared_ptr<MyParameter>));
};

TEST(LeakTest, GoogleMockLeaksMatchedPointer)
{
    shared_ptr<MyClassMock> c = make_shared<MyClassMock>();
    shared_ptr<MyParameterMock> p = make_shared<MyParameterMock>();
    {
        InSequence dummy;
        EXPECT_CALL(*c, myMethod(Eq(p)));
        EXPECT_CALL(*p, myMethod());
    }
    c->myMethod(p);
    p->myMethod();
}

このテストを実行すると、

leak_ptr_mock.cpp:37: ERROR: this mock object (used in test LeakTest.GoogleMockLeaksMatchedPointer) should be deleted but never is. Its address is @0x9309544.
ERROR: 1 leaked mock object found at program exit.

なぜこれが起こるのか考えていますか?私はむしろ使用する必要はありませんMock::AllowLeak

4

1 に答える 1

37

これは、保持pshared_ptr使用InSequence、および期待を宣言した順序の結果です。

電話すると

    EXPECT_CALL(*c, myMethod(Eq(p)));

use_countのを増やしますp。リーク検出を通過させるには、 をpの最後 (または前) に破棄する必要がありますTEST

ここでの問題は、内部的に、gmock が先行する期待値へのポインターを保持することによって、必要なモック呼び出しシーケンスの記録を保持していることです。したがって、 を呼び出すとEXPECT_CALL(*p, myMethod());、以前の期待値へのポインターのコピーが取得されます。

これは、終了p時に のデストラクタへの呼び出しをブロックする効果があります。TEST

これを回避するには、電話するのが最善の策だと思います

    EXPECT_TRUE(Mock::VerifyAndClearExpectations(p.get()));

終了する直前TEST。これにより、前提条件となる期待を含め、 の期待がクリアされp、 のデストラクタをp正しく呼び出すことができます。

あるいは、モック呼び出しの順序が重要でない場合は、単純に削除InSequence dummy;するだけでpのデストラクタも実行できます。


余談ですが、コードにはいくつかの問題があります。

  • 基本構造体には仮想デストラクタが必要です
  • MyClass::myMethodgmock の関数がそれをオーバーライドできるようにするには、virtual にする必要があります
  • p->myMethod(p);する必要がありますp->myMethod();
于 2012-04-23T22:29:18.703 に答える