2008-10-17 50 views
8

我寫了一些單元測試圍繞FTP服務器API測試一個包裝。我的單元測試應該在測試該API的包裝時直接觸摸API嗎?

單元測試和FTP服務器都在同一臺機器上。

包裝器API被部署到我們的平臺並用於遠程處理和Web服務場景。包裝API實質上是通過XML消息來執行任務,例如添加/刪除/更新用戶,更改密碼,修改權限等等。

在單元測試中,比方說要將用戶添加到虛擬域,我創建了要發送到API的XML消息。這個API可以工作並返回一個響應,其中包含有關操作是成功還是失敗(錯誤代碼,驗證失敗等)的狀態信息。

要驗證API包裝器代碼是否確實做了正確的事情(如果響應表示成功),我調用FTP服務器的COM API並直接查詢它的存儲以查看是否(例如創建用戶帳戶時)用戶帳戶確實已創建。

這味道不好嗎?

更新1: @ Jeremy/Nick:包裝是測試的重點,FTP服務器及其COM API是第三方產品,推測經過了充分測試和穩定。包裝器API必須解析XML消息,然後調用FTP服務器的API。我將如何驗證,這可能是一個愚蠢的情況,用戶帳戶的一個特定屬性由包裝器正確設置。例如,由於包裝代碼中的拼寫錯誤,設置FTP帳戶的錯誤屬性或屬性。一個很好的例子就是設置上傳和下載速度限制,這些可能會被轉換爲包裝代碼。

更新2:感謝所有的答案。對於那些建議使用mock的人來說,它已經超出了我的想法,但是燈光還沒有開啓,我仍然在努力讓自己的頭腦變得如何讓我的包裝與FTP服務器的模擬一起工作。 mock將駐留在哪裏,並且將所述mock的一個實例傳遞給包裝API以使用而不是調用COM API?我意識到嘲笑,但努力讓自己頭腦發熱,主要是因爲我發現大多數示例和教程都非常抽象,而且(我很慚愧地說)接近不可理解。

回答

7

你似乎是混合單元&組件測試問題。

  • 如果你是單元測試你的包裝,你應該使用模擬FTP服務器,而不涉及實際的服務器。好的一面是,你通常可以實現100%的自動化。
  • 如果您對組件進行組件測試(包裝器+ FTP服務器一起工作),請嘗試在與測試相同的級別驗證結果,即通過包裝器API進行驗證。例如,如果您發出上傳文件的命令,請發出命令刪除/下載該文件,以確保文件已正確上傳。對於測試結果並不重要的更復雜的操作,請考慮使用您提到的COM API「後門」,或者可能涉及一些手動驗證(您的所有測試是否需要自動化?)。
+1

已經研磨過的這種過度的年齡我現在終於明白,當我的單元測試,組件測試或集成測試以及它們的真正含義。 – Kev 2010-03-22 03:45:57

0

你在測試什麼包裝或API。 API應該按原樣工作,所以你不需要測試它,我會想。把你的測試工作集中在包裝上,並假裝API不存在,當我編寫一個文件訪問類時,我不會單元測試streamreader中的構建......我專注於我的代碼。

0

我會說你的API應該像測試時一樣處理數據庫或網絡連接。不要測試它,它不在你的控制之下。

0

這聽起來不像你問「我應該測試的API?」 - 你問:「我應該使用API​​來驗證我的包裝是否做得對嗎?」

我說是的。你的單元測試應該聲明你的包裝器傳遞了API報告的信息。例如,您舉例說,我不知道如何避免接觸API。所以我不認爲它味道不好。

3

要驗證API包裝代碼是否真的做正確的事(如果響應指示成功),我調用了FTP服務器的COM API

停在那兒。你應該嘲笑FTP服務器,包裝應該對付模擬。

如果你的測試運行包裝和FTP服務器,你不是單元測試。

0

我唯一能想到的是,如果更高級別的API是隻寫的,那麼在低級別API中驗證結果是否合理。例如,如果您可以使用高級API創建用戶,那麼應該有一個高級API來獲取用戶帳戶。使用它。

其他人建議嘲笑較低級別的API。這很好,如果你能做到的話。如果底層組件被模擬,檢查模擬以確保設置正確的狀態應該沒問題。

3

要使用模擬對象測試你的包裝,你可以做到以下幾點:

  • 編寫具有相同的接口作爲FTP服務器的COM API的COM對象。這將是你的模擬對象。你應該能夠通過依賴注入方式將接口指針傳遞給包裝器來交換真實的FTP服務器和你的模擬對象。
  • 你模仿的對象應該基於一種稱爲其接口(模仿FTP服務器API)的方法來實現硬編碼的行爲,並根據所使用的參數值:
  • 舉例來說,如果你有一個UploadFile方法,你可以一味地返回一個成功的結果,並可能將傳入的文件名存儲在一個字符串數組中。
  • 當你遇到一個帶有「錯誤」的文件名時,你可以模擬上傳錯誤。
  • 當您遇到文件名「slow」時,您可以模擬延遲/超時。
  • 稍後,DownloadFile方法可以檢查內部字符串數組,以查看具有該名稱的文件是否已被「上傳」。

一些測試用例的僞代碼將是:

//RealServer theRealServer; 
//FtpServerIntf ftpServerIntf = theRealServer.getInterface(); 

// Let's test with our mock instead 
MockServer myMockServer; 
FtpServerIntf ftpServerIntf = myMockServer.getInterface(); 

FtpWrapper myWrapper(ftpServerIntf); 

FtpResponse resp = myWrapper.uploadFile("Testing123"); 
assertEquals(FtpResponse::OK, resp); 

resp = myWrapper.downloadFile("Testing123"); 
assertEquals(FtpResponse::OK, resp); 

resp = myWrapper.downloadFile("Testing456"); 
assertEquals(FtpResponse::NOT_FOUND, resp); 

resp = myWrapper.downloadFile("SimulateError"); 
assertEquals(FtpResponse::ERROR, resp); 

我希望這有助於...

+1

真的很棒的回答!這基本上只是解釋了我試圖用單元測試和模擬對象來解決問題的一大堆事情。恥辱我不能給你超過一個upvote! – 2011-08-10 12:57:36