测试用例assertException [英] Testcase assertException

查看:849
本文介绍了测试用例assertException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图测试一个函数是否会抛出某个异常。

我发现这个答案女巫这样做:

  import Control.Exception 
import Control.Monad
import Test.HUnit

assertException ::(Exception e,Eq e)=>字符串 - > e - > IO a - > IO()
assertException preface预期操作=
handleJust isWanted(const $ return())$ do
操作
assertFailure msg
其中
isWanted = 。 (==预计)
msg = preface ++\\\
expected exception:++ show expected

testPasses = TestCase $ assertExceptionTest1DivideByZero(evaluate $ 5`div` 0 )
testFails = TestCase $ assertExceptionTest2DivideByZero(评估$ 5`div` 1)

main = runTestTT $ TestList [testPasses,testFails]
  

> ###失败:1
Test2
预计的例外情况:除以零
个案:2已尝试:2错误:0失败:1

assertException 不显示实际的异常或者没有显示异常



有没有办法显示实际的异常或缺失?

我试着用 catch 但我不知道如何将实际的异常传递给 msg

解决方案

以下是一种方法:

  { - #LANGU AGE ScopedTypeVariables# - } 

import Control.Exception
import Control.Monad
import Test.HUnit
import GHC.Natural

assertException4 ::(例外e,Eq e)=>字符串 - > e - > IO a - > IO()
assertException4 preface expected action = do
r < - 捕获
(action>> return(只是没有异常抛出))
[Handler(\ e - > return $ if e == expected
then Nothing
else Just(错误异常抛出,期望++ show expected ++,得到:++ show e))
- 查看下面有关这两个处理程序的注释:
,Handler(\e-> throw(e :: AsyncException))
,Handler(\(e :: SomeException) - > return $ Just(抛出一些其他异常:++ show e))
]
case r of
Nothing - > return()
只是味精 - > assertFailure(前言++:++ msg)

test1 = TestCase $ assertException4Test1DivideByZero(评估$ 5`div` 0)
test2 = TestCase $ assertException4Test2 DivideByZero(评估$ 5`div` 1)
test3 = TestCase $ assertException4Test3DivideByZero(评估$ [1,2,3] !! 4)
test4 = TestCase $ assertException4Test4DivideByZero (评估$(fromInteger(0-3):: Natural))

main = runTestTT $ TestList [test1,test2,test3,test4]
pre>

这四个测试用例是:


  1. 抛出DivideByZero异常 - 测试应该传递

  2. 没有异常抛出 - 测试失败

  3. 错误的异常抛出(不同类型) - 测试失败

  4. 错误的异常抛出(同一类型) - 测试失败

请注意,您必须有一个不同的catch处理程序对于与目标例外类型不同的例外。



Als o,我重新抛出任何AsyncException,因为这是HUnit在 performTestCase (链接)
打开Control-C将导致一个AsyncException,例如。



请注意,未捕获的异常将被HUnit报告为错误,并且将打印出异常。您可以通过删除AsyncException和SomeException的处理程序来进行测试。


I'm trying to test if a function throws a certain exception.
I found this answer witch does this:

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 ]

witch, when run, shows:

### Failure in: 1
Test2
expected exception: divide by zero
Cases: 2  Tried: 2  Errors: 0  Failures: 1

but assertException does not show the actual exception or if there isn't one

Is there a way to be able to show the actual exception or the absence?
I tried wrapping action with catch but I don't know how to pass the actual exception to msg.

解决方案

Here's one way to do it:

{-# 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 ]

The four test cases are:

  1. DivideByZero exception thrown - test should pass
  2. No exception thrown - test should fail
  3. Wrong exception thrown (of a different type) - test should fail
  4. Wrong exception thrown (of the same type) - test should fail

Note that you have to have a different catch handler for exceptions which are not of the same type as the target exception.

Also, I re-throw any AsyncException since that is what HUnit does in performTestCase (link) Hitting Control-C will cause an AsyncException, for instance.

Note that uncaught exceptions will be reported as Errors by HUnit, and the exception will be printed out. You can test this out by removing the handlers for AsyncException and SomeException.

这篇关于测试用例assertException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆