2012-09-14 36 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

太棒了!非常感谢你的帮助! –