2013-07-09 30 views
1

我正在嘗試使用Google Mock測試抽象類。繼forDummies指導,我已經構造我的課的模擬:在Google Mock上調用重載函數

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' : function does not take 1 arguments

我的理解是,由於MockFoo擴展AbstractFoo,它應該繼承setSize(QSize)方法。但是,這似乎並非如此。我怎樣才能解決這個問題?

編輯的代碼不準確

回答

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,你試圖實現的是不可能的。或通過鑄造MockFoo對象AbstractFoo&,然後調用此方法

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)方法解決這個問題:

下面的例子演示了同樣的問題。

你也可以看看NVI,因爲它看起來像你正在做的事情。

+0

感謝您指出。這些都是錯誤,因爲我構建了比我的實際代碼更短的示例,並且不存在於我的代碼中,該代碼仍然產生顯示的錯誤。 – bdares

+0

@bdares創建可編輯的示例後,我意識到問題到底是什麼。這就是C++的工作原理。 –

+0

感謝您的解釋,尤其是解決方法! – bdares

0

如果你正在搞亂超載的版本的成員方法,那麼你很可能會遇到gmock的問題。Google mock將每個模擬函數聲明爲單獨的函子對象,當然你可以重載函數對象,通常你會做的是重載函數對象內的單個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. 
} 

這將避免,谷歌內部模擬將產生一個對象與方法的名稱你正試圖宣佈。