2011-07-20 17 views
1

我需要一種方法來使鏈接器更喜歡一個實現而不是另一個。我的用例如下:我正在編寫單元測試,我需要模擬一些對象。問題是這些對象位於'main'庫中,即使在調試時我也不能扔掉它,因爲許多SDK都是在那裏生存的。如何讓鏈接器偏好實現從給定的位置

所以我實現了這些模擬,但現在看起來鏈接器更喜歡從'main'庫實現,至少我的代碼沒有被調用。如果這很重要,我將使用ARM RVCT 4 C++編譯器和Symbian工具鏈。

任何想法(甚至解決方法)非常感謝!編輯:我需要嘲笑靜態方法調用,並且可能這很重要,因爲我認爲靜態方法與普通方法相比以其他方式鏈接。

回答

1

通常嘲笑不會在鏈接階段完成,但可以在您的代碼中解決。 Dependency Injection是首選技術之一。也就是說,你應該模擬你的代碼,以便你可以在真實和模擬實現之間進行選擇。

例如,您想要在代碼中創建對象A.一種方法是在構建測試時有兩個不同的A實現並鏈接到模擬實現。依賴注入方法建議有一個指向接口的指針,並從外部(例如,在構造函數中)傳遞對象本身。然後,從生產代碼中,您將傳遞真實對象,並從單元測試中通過模擬。

如果您絕對需要在鏈接級別執行操作,並且無法避免鏈接「真實」對象,那麼您是否可以包裝這些對象?這裏有一個例子:

假設這是考驗你想要的代碼:

void my_method() 
{ 
    ProblematicClass c; 
    c.Call(); 
} 

ProblematicClass在兩個位置實現:一個SDK裏面另一個是你的模擬。如果你可以用ProblematicClass另一個類中,那麼你可以創建兩個源文件:

生產文件:

struct Wrapper 
{ 
public: 
    void Call() { m.Call(); } 

private: 
    ProblematicClass m; 
} 

模擬文件:

struct Wrapper 
{ 
public: 
    void Call() { m.Call(); } 

private: 
    MockClass m; 
} 

現在的來源是在你的控制,你不必更改測試代碼的設計,也可以排除生產實施。您的測試過程的代碼必須更改爲:

void my_method() 
{ 
    Wrapper c; 
    c.Call(); 
} 
+1

感謝您的回答。是的,這會有所幫助,但在目前的情況下,我不能遵循這種方式,出於某些原因(大量代碼需要重構,並且我們沒有時間這樣做)。順便說一下,在連接舞臺上嘲笑是一種非常流行的技術,至少在我們的項目中。但通常情況下,您可以通過不將它鏈接到exe來擺脫真正的實現,在我的具體情況下,由於問題中陳述的原因,這種方式是不可能的。 – Haspemulator

+0

關於你的編輯:是的,昨天我決定採取完全相同的方式,通過實施包裝和嘲笑它。所以我會接受你的新答案。 :) – Haspemulator