2011-09-30 61 views
37

我有一個工廠,返回一個智能指針。無論使用什麼智能指針,我都無法讓Google Mock嘲笑工廠方法。Google可以用智能指針返回類型來模擬一個方法嗎?

模擬對象是所有方法都是虛擬的純抽象接口的實現。我有一個原型:

MOCK_METHOD0(Create, std::unique_ptr<IMyObjectThing>()); 

我也得到:

"...gmock/gmock-spec-builders.h(1314): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'" 

類型指出,在智能指針定義。

我得到它試圖訪問一個聲明爲private的構造函數,但我不明白爲什麼。當這是一個std :: auto_ptr時,錯誤表示沒有複製構造函數,這讓我感到困惑。

無論如何,有沒有辦法模擬一個返回智能指針的方法?或者有更好的方法來建造工廠?我唯一的決心就是返回一個原始指針(blech ...)?

我的環境是Visual Studio 2010 Ultimate和Windows 7.我沒有使用CLI。

回答

-1

在大多數情況下,Google Mock要求模擬方法的參數和返回值是可複製的。每boost's documentation,unique_ptr不可複製。您可以選擇返回一個使用共享所有權的智能指針類(shared_ptr,linked_ptr等)並因此可複製。或者你可以使用一個原始指針。由於所討論的方法顯然是構造一個對象的方法,所以我沒有看到返回一個原始指針的固有問題。只要您將結果分配給每個呼叫站點的某個共享指針,您都會很好。

+31

你不需要對你的類的接口做任何改變,只是爲了讓它們與你的模擬框架一起工作。通常這是不可能的。這對我來說不是一個可接受的解決方案! –

+12

工廠類返回一個原始指針對我來說似乎是不可接受的。在這種情況下,unique_ptr最有意義。它的設計部分是爲了解決「將結果分配給*每個*呼叫站點上的某個共享指針」的問題。 –

+3

我不認爲這是正確的答案,將所有內容都改爲原始或共享所有權並不是一種解決方案,只是爲了測試事情! – paulm

78

谷歌模擬框架的非(可複製)函數參數和retun值問題的一個可行的解決方法是使用代理模擬方法。

假設你有下面的接口定義(如果它是良好的作風以這種方式使用std::unique_ptr似乎或多或少的一個哲學問題,我個人比較喜歡它強制過戶):

class IFooInterface { 
public: 
    virtual void nonCopyableParam(std::unique_ptr<IMyObjectThing> uPtr) = 0; 
    virtual std::unique_ptr<IMyObjectThing> nonCopyableReturn() = 0; 
    virtual ~IFooInterface() {} 
}; 

適當的模擬類可以定義是這樣的:

class FooInterfaceMock 
: public IFooInterface { 
public: 
    FooInterfaceMock() {} 
    virtual ~FooInterfaceMock() {} 

    virtual void nonCopyableParam(std::unique_ptr<IMyObjectThing> uPtr) { 
     nonCopyableParamProxy(uPtr.get()); 
    } 
    virtual std::unique_ptr<IMyObjectThing> nonCopyableReturn() { 
     return std::unique_ptr<IMyObjectThing>(nonCopyableReturnProxy()); 
    } 


    MOCK_METHOD1(nonCopyableParamProxy,void (IMyObjectThing*)); 
    MOCK_METHOD0(nonCopyableReturnProxy,IMyObjectThing*()); 
}; 

你只需要照顧,即配置(所採取的行動)的nonCopyableReturnProxy()方法在回報NULL或instanc在堆上動態分配。


有一個google-mock user forum thread討論這個話題,其中的維護者之一指出,谷歌,模擬框架不會改變,以支持該今後他們認爲他們的政策極力勸阻使用std::auto_ptr參數。如前所述,這是恕我直言的哲學觀點,而模擬框架的功能不應該引導您想要設計什麼樣的接口,或者您可以使用第三方API。

正如所說的答案描述了一個可行的解決方法。

+0

您鏈接到主要關於'auto_ptr'按值的討論中的線程是一個糟糕的計劃(和哦,哇,就像'auto_ptr'周圍的大部分事情一樣):但上面的問題是關於'unique_ptr',否? – Yakk

+0

@Yakk這是因爲我在我的實際測試用例中使用了'std :: auto_ptr',但同樣的原理也適用於'std :: unique_ptr'。你怎麼看,我是否應該相應地編輯問題? –

+0

只是這一點:「這種使用智能指針參數」 - 強烈的沮喪是關於'auto_ptr'參數,在'unique_ptr'存在之前於2010年編寫。修改框架以使'auto_ptr'能夠被濫用是一個相當可接受的位置:在'unique_ptr'出現之後這樣做是不同的一堆魚。如果你檢查他們將'auto_ptr'作爲一個合理的參數類型的原因,它們不適用於'unique_ptr'。 – Yakk

相關問題