2008-12-15 71 views
5

我正在開發一個有很多外部服務消息的項目。僅以一種稍微「雙曲線」的方式來描述它的一種好方法是系統必須將消息發送到Flicker API,Facebook API和Netflix API的應用程序。在測試之外使用模擬對象,不好的做法?

爲了支持斷開連接的場景,日誌問題,開發人員可用性,配置等......我已經嘗試過使用大量使用泛型和表達式樹的方法。最終的結果是這樣的:

Messenger<NetflixApi>.SendCustom(netflix => netflix.RecommendMovie("my message")); 

總的來說,我很高興與最終結果,但覺得我犯了一個錯誤,或者忽視與問候測試和斷開場景設計主要某處。

在測試過程中,無論是基於自動化,單元還是人爲的,我已經實現了一個對象工廠,最初使用DI在「實時模式」下執行正確的操作,並使用Mocks提供一種無菌信使,在測試模式下,什麼都做不了。

我只看到或讀過關於純粹TDD模式下使用的Mocks,而不是被用於某種愚蠢的對象。我所看到的方法將圍繞存根或嘲諷所使用的所有API所依賴的HTTP通信功能。

我主要關心的是,我希望連接到的所有不同的服務,我最終將不得不做大量細粒度的工作來取代特定的HTTP實現,如果我使用存根方法,我會有3個類用於這些服務(IService,ConcreteService,StubService)以及在實現新方法或更改任何內容時維護這些服務都是真正的PITA。

在目前的實現中,我使用Mocks來免費獲得「無菌模式」,幾乎不必爲了符合某個測試委託人而實施任何額外的任務。

問題是我錯過了什麼?我以更方便的方式違反了使用Mocks的設計負責人嗎?

任何人都可以提供任何建議,如何從許多不同的外部服務中獲得無菌模式,而無需跳過很多環節嗎?

這個問題有意義嗎?

感謝您的所有答案。

編輯#1:

我原來的問題並不清楚。任何null或mock對象都將純粹用於開發/調試/測試環境。在生產中,發送這些消息的代碼將是它們的實際實現。

我投票給每個人,因爲似乎有很多不同的解決方案來解決這個問題,我會探索每一個。

請不要認爲這個問題已經得到解答,我會盡我所能的讚賞。

回答

6

有一種名爲Null Object的設計模式。空對象是一個實現接口的對象,所以它可以用在像你這樣的場景中。

關於Null對象的重要之處在於,不要在可能破壞系統的地方返回null。

Null對象的目的是讓一個虛擬和簡單的東西的實現,就像一個模擬,但要在生產環境中使用。

最簡單的例子是這樣的:

class Logger{ 
private static ILogger _Logger; 

static Logger(){ 
    //DI injection here 
    _Logger = new NullLogger(); //or 
    _Logger = new TraceLogger(); 
} 
} 

interface ILogger{ 
void Log(string Message); 
} 

internal class TraceLogger:ILooger{ 
public void Log(string Message){ 
    //Code here 
} 
} 

internal class NullLogger{ 
public void Log(string Message){ 
    //Don't don anything, in purporse 
} 
} 

我希望這能幫助你

+0

第二次我看到這個線程的主題有一個紅色的「空對象」警報繼續... – abyx 2008-12-15 09:17:35

4

我想你可能需要澄清你的問題。 我不清楚你是否在測試中使用測試雙打而沒有存根或測試期望(所以用它們作爲假貨來滿足所需的界面),或者你是否在談論如何在生產場景中使用模擬來填充服務不可用(您的斷開連接的情況)。

如果您在測試情況下談論: 嘲笑是測試雙打。測試使用假貨而不是嘲笑或存根是沒有問題的。如果你不需要在特定的測試中使用這個服務,它只是在那裏提供一個給定的接口,即被測試的對象對它有依賴性,那就好了。這不是打破任何測試校長。

良好的嘲諷圖書館模糊了嘲笑,存根和假貨之間的界限。

查看Martin Fowler關於不同類型測試雙打的一些信息。 Mocks Aren't StubsTestDoubles

我真的很喜歡moq允許虛擬,假,存根和模擬對象之間的連續體的方式,而不需要跳過箍環來獲取特定行爲。 Check it out

如果你正在談論在斷開連接的場景中使用mock來生產......我會擔心的。假的是要返回空對象或默認值爲您所做的任何調用。這會將複雜性泄漏到所有使用這些服務的代碼中(它們需要處理檢查空返回值和空數組的操作)。我認爲對於斷開連接/無菌情況進行編碼以處理依賴關係本身不可用,而不是接受它們的模擬實現並繼續如同所有工作一樣,將會更有意義。

4

這聽起來像你對我可能想看看代理模式。即使與實際服務斷開連接,您也希望像各種服務一樣行事。因此,你的代碼會更好地與代理交談,而不是真實的交談。然後,根據當前的連接狀態,代理可以執行任何所需的操作。

相關問題