我可以编写一个带Test.HUnit
的测试用例来检查一个调用是否会抛出异常吗?
我只关心它是否会抛出任何错误,无论它打印什么信息。
答案 0 :(得分:2)
这不是特定于HUnit,但您可以编写一个函数来检查IO
值是否会抛出:
λ> :set -XScopedTypeVariables
λ> import Control.Exception
λ> import Data.Functor
λ> import System.Environment
λ> throws io = catch (io $> False) $ \(e :: SomeException) -> pure True
throws :: IO a -> IO Bool
λ> sequence $ throws <$> [ getEnv "HOME", getEnv "whatever", error "a" ]
[False,True,True]
答案 1 :(得分:2)
如果“异常”是指Exception
并且某些IO
代码被抛出,那么您可以使用catch
or catches
。但是,如果您的意思是在纯代码中捕获error "Something bad happened"
之类的内容,那么您就不走运了。如果您愿意在IO
中进行处理,您有更多选择:
ghci> import Control.Exception
ghci> catch (error "Eek") (\(ErrorCallWithLocation msg _) -> putStrLn msg)
Eek
来自Haskell 2010报告section 3:
表达式评估期间的错误,由⊥(“底部”)表示,Haskell程序与非终止无法区分。
这是考虑它的另一种方式:请注意,我们尝试评估⊥值(如error "Help!"
)时,不取决于此值是创建的时间,而只是当它第一次需要时(因为Haskell是非严格的)。捕获此类错误的机制将破坏参照透明度。