2012-09-14 37 views
6

我一直在想用什麼方法(如果有)用於測試通過網絡請求的Haskell應用程序?來自Ruby land,我一直在尋找任何可以爲了測試Haskell函數而存根或「模擬」網絡調用的東西。我對「類似VCR」的解決方案特別感興趣(例如:https://github.com/myronmarston/vcr),因爲它似乎是最可行的選擇,恕我直言。Haskell:測試web API

所以,我希望能夠記錄一次網絡請求/響應對,然後重新使用這些記錄進行後續測試。我已經提出了自己的簡單調製,在測試之前啓動一個Web服務器(warp),爲預先記錄的響應提供服務,但是我必須將應用程序中的所有URL指向「localhost」。我認爲,這並不總是可以取代應用程序中的所有URL。雖然我對上述自己的設置感到非常滿意(並且希望稍後可以製作一個專用的測試工具/框架「插件」),但我寧願不要重新發明輪子。

+0

我已經基於VCR的想法開始了一個Haskell項目。貢獻或發送反饋,如果您願意:https://github.com/cordawyn/havcr –

回答

3

結賬Control.Proxy.Tutorial。如果你可以寫在你的類型代理的包裝,那麼你就可以輕鬆更換測試接口和一個真正的接口是這樣的:

client <-< simulatedServer 

client <-< realServer 

編輯:要回答在評論你的問題,你用Server寫在你simpleHTTP要求的包裝:

realServer 
:: HStream ty => Request ty -> Server (Request ty) (Result (Response ty)) IO r 
realServer = foreverK $ \req -> do 
    result <- lift $ simpleHTTP req 
    respond result 

模擬服務器看起來像:

simulatedServer 
:: (Monad m, HStream ty) 
=> Request ty -> Server (Request ty) (Result (Response ty)) m r 
simulatedServer = foreverK $ \req -> do 
    result <- lift $ simulatedRequest req 
    respond result 

和你的客戶會看上去像個E:

client 
:: (Monad m, HStream ty) =>() -> Client (Request ty) (Result (Response ty)) m r 
client() = forever $ do 
    let req = <something> 
    result <- request req 
    lift $ doSomethingWith result 

然後你可以使用測試真實服務器和假服務器:

-- Test the real server 
main = runSession $ client <-< realServer 

-- Test the fake server 
main = runSession $ client <-< simulatedServer 

clientsimulatedServer是在基礎單子多態不僅是因爲我不知道是什麼單子基地,他們將用於測試。唯一的要求是你構成的兩件事物具有相同的基本monad,或者至少有一個在基本monad中是多態的。

+0

因此,基本上,我當前的'Network.HTTP.simpleHTTP req'在客戶端成爲'Control.Proxy.request req',然後我爲「realServer」放置'Control.Proxy.respond $ Network.HTTP.simpleHTTP req',爲「simulatedServer」放置'Control.Proxy.respond $ Simulated.Network req'。 然後我按照上圖所示鏈接它們。 這是正確的嗎? –

+0

@SlavaKravchenko是的。我編輯了我的答案,以便給出具體的代碼示例,說明如何做到這一點,以便我確切知道您的想法。 –

+0

太棒了!非常感謝你的幫助! –