我正在尝试测试一个函数是否抛出某个异常。
我发现这个答案女巫是这样做的:
import Control.Exception
import Control.Monad
import Test.HUnit
assertException :: (Exception e, Eq e) => String -> e -> IO a -> IO ()
assertException preface expected action =
handleJust isWanted (const $ return ()) $ do
action
assertFailure msg
where
isWanted = guard . (== expected)
msg = preface ++ "\nexpected exception: " ++ show expected
testPasses = TestCase $ assertException "Test1" DivideByZero (evaluate $ 5 `div` 0)
testFails = TestCase $ assertException "Test2" DivideByZero (evaluate $ 5 `div` 1)
main = runTestTT $ TestList [ testPasses, testFails ]
女巫在奔跑时显示:
### Failure in: 1
Test2
expected exception: divide by zero
Cases: 2 Tried: 2 Errors: 0 Failures: 1
但assertException
不会显示实际的异常或没有异常
有没有办法能够显示实际的异常或缺失?
我尝试用包装动作,catch
但是我不知道如何将实际的异常传递给msg
。
这是一种实现方法:
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Exception
import Control.Monad
import Test.HUnit
import GHC.Natural
assertException4 :: (Exception e, Eq e) => String -> e -> IO a -> IO ()
assertException4 preface expected action = do
r <- catches
(action >> return (Just "no exception thrown"))
[ Handler (\e -> return $ if e == expected
then Nothing
else Just ("wrong exception thrown, expected " ++ show expected ++ ", got: " ++ show e))
-- see the comments below about these two handlers:
, Handler (\e -> throw (e :: AsyncException))
, Handler (\(e::SomeException) -> return $ Just ("some other exception thrown: " ++ show e))
]
case r of
Nothing -> return ()
Just msg -> assertFailure (preface ++ ": " ++ msg)
test1 = TestCase $ assertException4 "Test1" DivideByZero (evaluate $ 5 `div` 0)
test2 = TestCase $ assertException4 "Test2" DivideByZero (evaluate $ 5 `div` 1)
test3 = TestCase $ assertException4 "Test3" DivideByZero (evaluate $ [1,2,3] !! 4)
test4 = TestCase $ assertException4 "Test4" DivideByZero (evaluate $ (fromInteger (0 - 3) :: Natural) )
main = runTestTT $ TestList [ test1, test2, test3, test4 ]
四个测试用例是:
请注意,对于与目标异常类型不同的异常,您必须具有不同的catch处理程序。
另外,我重新抛出任何AsyncException,因为例如HUnit在performTestCase
(链接)命中Control-C时将执行此操作,将导致AsyncException。
请注意,未捕获的异常将由HUnit报告为“错误”,并且该异常将被打印出来。您可以通过删除AsyncException和SomeException的处理程序进行测试。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句