异常的单元测试

时间:2016-12-13 17:48:38

标签: haskell hunit

我可以编写一个带Test.HUnit的测试用例来检查一个调用是否会抛出异常吗?

我只关心它是否会抛出任何错误,无论它打印什么信息。

2 个答案:

答案 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是非严格的)。捕获此类错误的机制将破坏参照透明度。