2012-09-14 12 views
6

私は、ネットワーク上の要求を行うHaskellアプリケーションのテストにどのようなメソッドが使用されているのだろうと考えていますか? Rubyの土地から来て、私はハスケル関数をテストする目的で、ネットワーク呼び出しをスタブまたは「シミュレート」できるものを探してきました。私はとりわけ "VCR"のようなソリューション(例えばhttps://github.com/myronmarston/vcr)に興味があります。これは最も実行可能なオプションのようです。Haskell:Web APIのテスト

したがって、ネットワークの要求/応答のペアを一度記録し、その後のテストでこれらのレコードを再利用できるようにしたいと考えています。テストの前にウェブサーバ(ワープ)を起動し、あらかじめ記録されたレスポンスを提供する私自身の単純な組み合わせを考え出しましたが、アプリケーション内のすべての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は、私が何をベースモナド彼らは希望を知らないだけであるため、ベースモナドで多形性あなたのテストのために使用してください。唯一の要件は、あなたが構成する2つのものが同じ基本モナドを持つか、少なくとも1つが基本モナドの多形であるということです。

+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

恐ろしい!助けてくれてありがとう! –