[英]How to test with hspec whether the readerError function was executed
我是Haskell的新手。
我編寫了以下代碼,將解析發送到腳本的參數;
module Billing.Options
(
GlobalOpts(..)
, globalOptsParser
, parseDb
) where
import Options.Applicative
import Options.Applicative.Simple
import Options.Applicative.Types
import System.FilePath.Posix
import Text.Regex.PCRE
-- ------------------------------------------------------------
data GlobalOpts = GlobalOpts
{
optDb :: String,
optSql :: String
} deriving Show
-- ------------------------------------------------------------
globalOptsParser :: Parser GlobalOpts
globalOptsParser = GlobalOpts
<$> option (parseDb =<< readerAsk)
( long "db"
<> short 'd'
<> metavar "<DB name>"
<> help "dmt | report"
)
<*> option parseSql
( long "sql"
<> metavar "<SQL SELECT statement>"
<> help "sql select statement to use in order to generate JSON config file"
)
-- ------------------------------------------------------------
matches :: String -> String -> Bool
matches = (=~)
-- ------------------------------------------------------------
parseDb :: String -> ReadM String
parseDb val = do
if not (elem val ["dmt", "report"])
then readerError $ "Unknown DB, '" ++ val ++ "'"
else return val
-- ------------------------------------------------------------
parseSql :: ReadM String
parseSql = do
val <- readerAsk
if not (val `matches` "(?i)select .+ from .+")
then readerError $ "Please provide a valid SQL SELECT statement"
else return val
-- [EOF]
我想用hspec測試上面的“ parseDb”功能。 我想確保在指定未知數據庫時將引發“ readerError”。 因此,我想測試該函數調用parseDb“ unknown”生成一個“ readerError”調用,根據我的說法,該調用應引發異常。
我已經嘗試了hspec shouldThrow函數,但是它不起作用。 似乎沒有異常被拋出。 readerError的返回類型為“ ReadM a”。 在花了幾天時間閱讀了monad和讀者monad之后,我仍然很困惑(並且很困惑),不知道如何進行測試以及是否有可能進行測試。 谷歌搜索時找不到任何相關示例。
以下是一些相關的類型信號:
parseDb :: String -> ReadM String
-- from Options.Applicative.Internal
runReadM :: MonadP m => ReadM a -> String -> m a
runP :: P a -> ParserPrefs -> (Either ParseError a, Context)
runReadM
和runP
文檔:( 鏈接)
ParserPrefs
只是一個簡單的數據結構。
並且此類型檢查:
import Options.Applicative.Types
import Options.Applicative.Internal
parseDb :: String -> ReadM String
parseDb val = do
if not (elem val ["dmt", "report"])
then readerError $ "Unknown DB, '" ++ val ++ "'"
else return val
foo :: (Either ParseError String, Context) -- might be [Context] now
foo = runP (runReadM (parseDb "foo") "asd") opts
where opts = ParserPrefs "suffix" False False False 80
評估fst foo
返回:
*Main> fst foo
Left (ErrorMsg "Unknown DB, 'foo'")
更新
這是測試像globalOptsParser這樣的Parser
方法 :
import Options.Applicative.Common (runParser)
import Options.Applicative.Internal (runP)
bar = let mp = runParser AllowOpts globalOptsParser ["asd"]
opts = ParserPrefs "suffix" False False False 80
in fst $ runP mp opts
這里["asd"]
是要測試的命令行參數。
檢查ParserPrefs
是否是您想要的-它們會影響選項處理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.