代码之家  ›  专栏  ›  技术社区  ›  Jesse Shieh José Valim

哈斯克尔:如何测试使用wreq的spock应用程序?

  •  3
  • Jesse Shieh José Valim  · 技术社区  · 6 年前

    我用haskell编写了一个非常简单的应用程序 Spock wreq . 我想写一些测试,但我不知道怎么做。

    该应用程序所做的就是向另一个服务器发出一个HTTP请求,并将JSON响应转换为一条对人友好的消息。这是 the code 如果有帮助的话。我想编写一个测试,在给定某个JSON响应的情况下,断言人性化消息是正确的。

    在Ruby中,我将模拟出HTTP客户机,在本例中 wreq ,以控制我得到的JSON响应,但我不确定如何或即使在Haskell中这样做。

    根据我从研究中收集到的资料,听起来 type-class-constrained type variables 是一种方式,对我来说,这看起来像依赖注入,但是我不确定如何在spock和wreq的上下文中进行。

    这个 Spock testing tutorial 描述如何在 IO Application 听起来不错的水平。我不确定的部分是如何“注入”一个模拟HTTP客户机来控制JSON响应。

    感谢您的帮助!

    1 回复  |  直到 6 年前
        1
  •  2
  •   danidiaz    6 年前

    如果我们想要支持不同的请求方法,我们必须对它们进行抽象。您可以使处理程序接受执行HTTP请求的函数作为参数,然后传递不同的函数用于测试和生产。如果您有多个相关函数,请将它们放在一个记录中 handle pattern )


    如果我们使用 cabal-install >2.0(带 new-* commands )另一个可能的选择是使用 module signature 在测试套件和最终可执行应用程序之间切换实现。该解决方案还充分利用了 internal convenience libraries 阴谋集团的特征。

    基本思想是:我们将spock应用程序放在自己的库中,但不要使它依赖于 wreq 直接。相反,我们在同一个库中声明一个签名 Requests.hsig 这样地:

    signature SomeSpockApp.Requests where
    
    import           Data.Aeson (FromJSON)
    
    data Token
    
    doGET :: FromJSON a => String -> Token -> IO a 
    

    它为执行HTTP请求定义了一个高级接口。库中的代码将导入此签名。对于库中的其余代码, SomeSpockApp.Requests 只是另一个模块。

    接下来,我们定义一个方便的库,它将提供一个实际的模块 somespockapp.请求 (与签名同名,但现在它是 hs 文件)。它将包含“模拟”代码。当然,定义 doGET 必须与签名兼容。

    我们还定义了另一个便利库 somespockapp.请求 模块。这个应该依赖于wreq并使用wreq的函数来实现我们的签名方法。

    在测试套件中 我们应该同时依赖Spock应用程序库和模拟库。签名和模拟实现模块的名称完美地排列在一起,因此不需要再做任何事情。(如果名称不匹配,我们可以使用 mixins 在cabal文件中的节来重命名模块)。

    在应用程序可执行文件中, 我们应该同时依靠我们的spock应用程序库和wreq使用库。