haskell - Hspec:发现、自定义 main 以及将参数传递给规范

标签 haskell hspec

我正在尝试将 hspec-discover 与自定义 Main 一起使用。自定义 Main 是一个 bracket,它创建一个供所有 Spec 使用的文件描述符。

这是我的Spec.hs:

{-# OPTIONS_GHC -F -pgmF hspec-discover -optF --module-name=Spec #-}

这是我的Main.hs:

module Main (main) where

import Control.Exception
import System.Posix.IO
import System.Posix.Files
import Test.Hspec
import Spec (spec)

main :: IO ()
main = bracket
  (openFd verybigFile ReadWrite (Just 384) defaultFileFlags)
  (\fd -> closeFd fd >> removeLink verybigFile)
  (\fd -> hspec (spec fd))
    where
      verybigFile = "test/verybigFile"

为了让单独的自动发现模块中的 spec 接受文件描述符参数,我需要将其声明为

spec :: Fd -> Spec

但是hspec-discover要求将spec声明为

spec :: Spec

否则自动生成的模块无法编译:

test/Spec.hs:8:68:
    Couldn't match type `System.Posix.Types.Fd -> Spec'
                  with `hspec-core-2.1.7:Test.Hspec.Core.Spec.Monad.SpecM () ()'
    Expected type: hspec-core-2.1.7:Test.Hspec.Core.Spec.Monad.SpecWith
                     ()
      Actual type: System.Posix.Types.Fd -> Spec
    In the second argument of `describe', namely `SendfileSpec.spec'
    In the second argument of `postProcessSpec', namely
      `(describe "Sendfile" SendfileSpec.spec)'
    In the expression:
      postProcessSpec
        "test/SendfileSpec.hs" (describe "Sendfile" SendfileSpec.spec)

那么,如何在不干扰自动发现的情况下将参数传递给规范?我的想象力转向了 IORef,但这个想法让我不寒而栗。什么是正确的方法?

最佳答案

hspec-discover 目前不支持跨规范文件共享值。但您仍然可以在同一规范文件中共享值。作品如下:

FooSpec.hs:

module FooSpec (spec) where

import           Test.Hspec
import           System.IO

spec :: Spec
spec = beforeAll (openFile "foo.txt" ReadMode) $ afterAll hClose $ do
  describe "hGetLine" $ do
    it "reads a line" $ \h -> do
      hGetLine h `shouldReturn` "foo"

    it "reads an other line" $ \h -> do
      hGetLine h `shouldReturn` "bar"

Spec.hs:

{-# OPTIONS_GHC -F -pgmF hspec-discover #-}

但请注意,beforeAll 通常被认为是代码异味。如果可能的话,最好使用before

关于haskell - Hspec:发现、自定义 main 以及将参数传递给规范,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30631737/

相关文章:

haskell - 从 Cabal 向 HSpec 提供选项

Haskell - 断言一个函数被调用

haskell - HSpec 无预期编译失败

Haskell 在(理论上)不应该出现的情况下陷入僵局

json - Aeson 合并对象编码

Haskell GHC : what is the time complexity of a pattern match with N constructors?

haskell - Aeson 或 Wai.JSON QuasiQuoter 的问题 -- 将 0.0 转换为 0

haskell - 使用 HSpec 和 QuickCheck 验证 Data.Monoid 属性

haskell - Haskell 中的目录内容

haskell - 在 Haskell 中应用函数并包装在元组中