1

Google Mock を使用して抽象クラスをテストしようとしています。forDummiesガイドに従って、クラスのモックを作成しました。

AbstractFoo.h

class AbstractFoo {
public:
  virtual void setSize(int w, int h) = 0;
  void setSize(const QSize& s); // implemented as calling above function
}

MockFoo.h

#include "gmock/gmock.h"
class MockFoo : public AbstractFoo {
public:
  MOCK_METHOD2(setSize, void(int w, int h));
}

FooTest.cpp

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "MockFoo.h"

TEST(AbstractFoo, MethodSetSize) {
  MockFoo foo;
  EXPECT_CALL(foo, setSize(5, 5)).Times(1);
  foo.setSize(QSize(5, 5)); // this line produces compiler error
}

マークされた行は、次のコンパイラ エラーを生成します。

C2660: 'MockFoo::setSize': 関数は引数を 1 つ取りません

私の理解では、MockFooextendsであるため、メソッドAbstractFooを継承する必要があります。setSize(QSize)ただし、そうではないようです。どうすればこれを修正できますか?

コードの不正確さのために編集

4

2 に答える 2

3

互いにオーバーロードされたバージョンのメンバー メソッドをいじっていると、gmock で問題が発生する可能性があります。Google モックは、モックされた各関数を個別のファンクター オブジェクトとして宣言します。もちろん、ファンクター オブジェクトをオーバーロードできますが、通常行うことは、ファンクター オブジェクト内の個々の operator()(...) メソッドをオーバーロードすることです。

私は通常、ラッパーのモック関数を宣言し、それをオーバーロードされた関数から呼び出すことで、この問題を回避します。ヘッダーは次のようになります。

MockFoo.h

#include "gmock/gmock.h"
class MockFoo : public AbstractFoo {
  public:
    void setSize(int w, int h) {
      mocked_setSize(w, h);  ///< workaround to call the mocked setSize instead.
    }

    MOCK_METHOD2(mocked_setSize, void(int w, int h));
}

したがって、すべての呼び出しsetSize(w,h)はメソッドに向けられますmocked_setSize(w,h)。これは、単体テストで次のことを行う必要があることを意味します。

MockFoo.cpp

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "MockFoo.h"

TEST(AbstractFoo, MethodSetSize) {
  MockFoo foo;
  EXPECT_CALL(foo, mocked_setSize(5, 5)).Times(1);
  foo.setSize(QSize(5, 5)); ///< now this should compile cleanly.
}

これにより、宣言しようとしているメソッドの名前で Google モックが内部的にオブジェクトを生成することを回避できます。

于 2014-06-20T11:11:24.000 に答える
1

モック クラスのメソッドのシグネチャが間違っています:

MOCK_METHOD2(setSize, bool(int w, int h));

基本クラスには、次のシグネチャを持つメソッドがあります。

virtual void setSize(int w, int h) = 0;

どのコンパイラを使用しているかはわかりませんが、コンパイラ エラーである必要があります。

署名を修正すると、エラーは解消されます:

MOCK_METHOD2(setSize, void(int w, int h));

さらに、

class MockFoo : AbstractFoo

する必要があります

class MockFoo : public AbstractFoo

あなたの問題は googlemock ライブラリとは関係ありませんが、c++ とは関係ありません。[class.virtual]/1 のため、達成しようとしていることが不可能です。

次の例は、同じ問題を示しています。

struct A
{
    A(int h,int l):x(h),y(l){}
    int x; int y;
};

class AbstractFoo {
public:
    virtual void setSize(int w, int h) = 0;
    void setSize(const A& s){setSize(s.x,s.y);}
};

class MockFoo : public AbstractFoo
{
public:
    void setSize(int , int ){}
};

int main()
{
    MockFoo f;
    A a(5,5);

    f.setSize( a );
}

この問題は、メソッドの名前を変更するか、オブジェクトをsetSize(const QSize& s)キャストしてからこのメソッドを呼び出すことで解決できます。MockFooAbstractFoo&

NVIを調べることもできます。それは、あなたがやろうとしているように見えるからです。

于 2013-07-09T06:02:40.457 に答える