6

生のポインターで正常に機能するテストがありますが、で機能させるのに問題があり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_は、はテストのスタックで作成されたモック/フェイクであり、アドレスをのコンストラクターに渡しますMyClass。としてMyClass取るように変更すると、私の新しいクラスは次のようになります。serviceshared_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_ptrto service_(偽のオブジェクト)が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());て、今のところこの問題を回避できます。うまくいけば、私は答えを得るでしょう。

4

2 に答える 2

8

テスト クラスを次のように定義します。

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);
于 2012-04-26T22:05:41.690 に答える
2

これは、テスト フレームワークとは関係ありません。あなた自身が言ったように、スタック割り当てオブジェクト (つまり、自動有効期間を持つオブジェクト) から shared_ptr を作成しています。これは意味がありません。共有ポインタは通常、 の結果から作成されnewます。カスタムの Deleter を shared_ptr コンストラクターの 2 番目の引数として渡すと機能する可能性がありますが、new を使用してオブジェクトを作成することをお勧めします。

于 2012-04-26T21:42:07.783 に答える