如果我们想支持不同的请求方法,我们必须对它们进行抽象。您可以让您的处理程序接受一个执行 HTTP 请求的函数作为参数,然后传递不同的函数进行测试和生产。如果您有多个相关功能,请将它们放在记录中(句柄模式)。
如果我们使用cabal-install > 2.0(使用new-* commands),另一个可能的选择是使用模块签名在测试套件和最终可执行应用程序之间切换实现。该解决方案还大量使用了 Cabal 的内部便利库功能。
基本思想是这样的:我们将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.Requests(与签名同名,只是现在它是一个hs文件)。它将包含“模拟”代码。当然,定义doGET必须与签名兼容。
SomeSpockApp.Requests我们还用另一个模块定义了另一个便利库。这个应该依赖于 wreq 并使用 wreq 的函数来完成我们签名的方法。
在测试套件中,我们应该同时依赖 Spock 应用程序库和模拟库。签名和模拟实现模块的名称完美对齐,因此无需再做任何事情。(如果名称不匹配,我们可以使用 cabal 文件中的mixins节来重命名模块)。
在应用程序可执行文件中,我们应该同时依赖 Spock 应用程序库和 wreq-using 库。