2015-04-12 39 views
0

我想測試一個特定的方法是否會產生預期的結果,但要做到這一點,我還需要在測試中操作輸入。我是否應該在實際課程中重複代碼

class ToTest { 
    public String produceResponse(String input) { 
    // .... 
    encryptedIds = encryptIds(input) 
    output = doStuff(input, encryptedIds) 
    } 

    public encryptIds(input) { 
    .... 
    } 
} 

在我的測試中,我需要檢查produceResponse實際上是否產生預期的響應。 爲了做到這一點,我必須加密輸入中的ID。

我的問題是:我應該在測試中重寫encryptIds(這樣我就可以有更多的控制器)或者我應該從類本身調用encryptIds。

有沒有更好的方法來解決這個問題?我不喜歡我的測試,我知道特定流程會發生什麼。

回答

3

如果我理解正確,你想測試produceResponse()已知encryptedIds作爲輸入。

你可以做,沒有重構的代碼,但它很可能是一個好主意,重構它,所以這就是我要解釋一下:

class ToTest { 

    private IdEncryptor encryptor; 

    public ToTest(IdEncryptor encryptor) { 
     this.encryptor = encryptor; 
    } 

    public String produceResponse(String input) { 
     String[] encryptedIds = encryptor.encryptIds(input); 
     return doStuff(input, encryptedIds); 
    } 
} 

現在,您可以單元測試IdEncryptor到測試它是否會根據字符串輸入生成正確的加密ID。

要測試ToTest類,您可以模擬IdEncryptor,以便無論接收到什麼輸入,它都會生成您想要的encryptedIds。例如與mockito:

IdEncryptor mockEncryptor = mock(IdEncryptor.class); 
when(mockEncryptor.encryptIds(any(String.class)).thenReturn(new String[] {"a", "b"}); 

ToTest toTest = new ToTest(mockEncryptor); 
String response = toTest.produceResponse("input"); 
// expect that the response is what you expect given "a", "b" as input of doStuff() 
0
  1. 切勿將任何生產代碼複製到單元測試中,因爲它會在某個時間點過期。
  2. 如果這兩種方法是公開的,他們是公共API的一部分,所以:

    • 你應該先單元測試encryptIds(String)方法
    • 然後單元測試produceResponse(String)方法的正確行爲,將內部使用已經測試encryptIds(String)方法
  3. 如果encryptIds(String)不會是公共API的一部分:

    • 那麼它是內部實現和輔助方法,是不是可以進行單元測試
    • produceResponse(String)然後用於加密的副作用負責:
      • 你仍然可以測試它,如果你將其標記包專用(無改性劑)
      • 你也可以改變encryptIds(String)實施僅用於測試目的
+0

如果encryptIds不是API的一部分,該怎麼辦? – user844541

+0

增加了更多描述 – Crazyjavahacking

0

是加密id的東西是不可或缺的東西是你的系統?就目前而言,這門課程需要一些輸入併產生一些輸出,並且就您的測試而言,這是重要的,不多也不少。

不執行加密的影響是什麼?如果你的doStuff方法如果沒有發生就會失敗,那麼它就是你的待測類的內部細節,我根本就不會關心它。如果這是絕對必須執行的步驟,那麼我會重構代碼以驗證它絕對發生了,也許使用@ jb-nizet的模擬回答。

至於重複生產代碼測試,@Crazyjavahacking說,你不應該這樣做的一般情況,但我必須使用帶有沒有問題生產代碼從測試 - 也許不是在單元級,但絕對是比我更高的系統,例如當測試寫入數據庫時​​,我將使用讀取代碼來驗證它是否正確發生,但也將有獨立測試來驗證讀取路徑以及

相關問題