簡體   English   中英

用C ++實現模擬

[英]Mock implementations in C++

我需要一個類的模擬實現 - 用於測試目的 - 我想知道我應該如何做到這一點。 我可以想到兩種一般方式:

  1. 創建一個包含該類的所有公共函數的接口作為純虛函數,然后通過派生它來創建一個模擬類。
  2. 將所有函數(至少是所有要模擬的函數)標記為虛擬

我習慣於在Java中使用它的第一種方式,它也很常見(可能因為它們有專用的接口類型)。 但是我幾乎沒有在C ++中看到這種界面沉重的設計,因此我很想知道。

第二種方式可能會起作用,但我不禁想到它有點難看。 有人這樣做嗎?

如果我按照第一種方式,我需要一些命名幫助。 我有一個音頻系統,負責加載聲音文件和播放加載的曲目。 我正在使用OpenAL,因此我將接口稱為“音頻”和實現“OpenALAudio”。 但是,這意味着所有特定於OpenAL的代碼都必須進入該類,這感覺有點限制。 另一種方法是保留類“名稱”Audio“並為界面找到不同的名稱,例如”AudioInterface“或”IAudio“。 你會建議哪個,為什么?

就像我不會在Java中手工創建模擬對象一樣,我也不會用C ++手工創作它們。 模擬對象不僅僅是存根類,而是執行自動檢查的測試工具,例如確保調用某些方法,或者按順序調用它們等等。我會看一下C ++的各種模擬對象框架。 。 googlemock看起來很有趣,但還有其他的。

關於如何從實現中抽象出控制音頻資源的概念,我絕對贊成使用帶有通用名稱的C ++“接口”(純虛擬基類)(例如Audio )和一個以其特殊性命名的實現類(例如OpenALAudio )。 我建議你不要在你的班級名稱中嵌入“interface”或“I”這個詞。 將類型或程序化概念嵌入到名稱中已經不再流行多年(例如,當您將“界面”提升為完整的“類”時,可以強制進行廣泛的重命名)。

開發接口是面向對象的概念,因此適用於C ++。 一些關於設計專門針對C ++的最重要的書籍都是關於接口編程(用C ++術語來表示使用純虛擬基類編程)。 例如, 設計模式大規模C ++軟件設計

“但我幾乎沒有在C ++中看到這種界面密集的設計”,對於您的信息,我建議您只是簡單地看一下微軟COM的做法。 這種基於C ++的技術完全是面向接口的設計。

通過接口設計是一種很好的編程方式。 如果你習慣了,繼續這樣做。

如果您發現自己受限於名稱,則使用名稱空間是一種很好的做法。 對於接口名稱,通常將它們稱為ISomething,因此只需將其稱為IAudio即可。

我會說這很大程度上取決於具體情況和模擬所需的復雜性。 我認為理想情況下你會使用原始版本,但是由於復雜的依賴性而希望避免使用原文。 然后,在繼續開發測試代碼時,可能需要復制粘貼標題並注釋掉所有內容並根據需要重新啟用模擬功能。

我必須承認我沒有這方面的實際經驗,但在我看來,你在原始代碼中的侵擾性越小越好。

您是否考慮使用像Hippo Mocks這樣的模擬框架?

來自維基

class Foo {
private:
    IBar *bar;
public:
    Foo(IBar *bar);
    int a(); //calls IBar::c
};

class IBar {
public:
    virtual ~IBar() {}
    virtual void b() = 0;
    virtual int c(std::string) = 0;
};

void TestAFunctionInFoo() {
    MockRepository mocks;
    IBar *barMock = mocks.InterfaceMock<IBar>();
    Foo *newFoo = new Foo(barMock);
    mocks.ExpectCall(barMock, IBar::c).With("hello").Return(42);
    newFoo->a();
    delete newFoo;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM