简体   繁体   中英

Unit testing for exceptions

Can I write a test case with Test.HUnit that checks whether a call throws an exception?

I only care whether it throws any error, regardless of what message it prints.

This isn't specific to HUnit, but you can write a function to check whether an IO value throws:

λ> :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]

If by an "exception" you mean Exception and it is being thrown in some IO code, then you can use catch or catches . However, if you mean catching things like error "Something bad happened" in pure code , you are out of luck. If you are willing to do the handling in IO , you have more options:

ghci> import Control.Exception
ghci> catch (error "Eek") (\(ErrorCallWithLocation msg _) -> putStrLn msg) 
Eek

From the Haskell 2010 report section 3 :

Errors during expression evaluation, denoted by ⊥ (“bottom”), are indistinguishable by a Haskell program from non-termination.

Here is another way to think about it: notice that the moment we try to evaluate a value that is ⊥ (like error "Help!" ) depends not on when this value was created but only when it was first needed (since Haskell is non-strict). A mechanism to catch this sort of error would then break referential transparency.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM