Hspec:发现、自定义 main 并将参数传递给 spec
Hspec: discovery, custom main, and passing argument to spec
我正在尝试将 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
否则自动生成的模块无法编译:
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
。
我正在尝试将 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
否则自动生成的模块无法编译:
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
。