unit-testing - 如何测试 Haskell 中的错误?

标签 unit-testing testing haskell error-handling hunit

我希望能够确保函数在接收到无效值时会抛出错误。例如,假设我有一个函数 pos 只返回一个正数:

pos :: Int -> Int
pos x
   | x >= 0 = x
   | otherwise = error "Invalid Input"

这是一个简单的示例,但我希望您能理解。

我希望能够编写一个预期会出现错误并将其视为通过测试的测试用例。例如:

tests = [pos 1 == 1, assertError pos (-1), pos 2 == 2, assertError pos (-2)]
runTests = all (== True) tests

[我的解决方案]

这就是我根据@hammar 的评论最终采用的方法。

instance Eq ErrorCall where
    x == y = (show x) == (show y)

assertException :: (Exception e, Eq e) => e -> IO a -> IO ()
assertException ex action =
    handleJust isWanted (const $ return ()) $ do
        action
        assertFailure $ "Expected exception: " ++ show ex
  where isWanted = guard . (== ex) 

assertError ex f = 
    TestCase $ assertException (ErrorCall ex) $ evaluate f

tests = TestList [ (pos 0) ~?= 0
                 , (pos 1) ~?= 1
                 , assertError "Invalid Input" (pos (-1))
                 ]   

main = runTestTT tests

最佳答案

OP 的解决方案定义了 assertException,但它看起来像来自 testpackTest.HUnit.Tools.assertRaises也可以在这里使用。

我将 msg 参数添加到 assertError 以匹配 assertRaises 的工作方式,并包含选择性导入,以便像我这样的菜鸟可以了解常用的地方东西是从进口的。

import Control.Exception (ErrorCall(ErrorCall), evaluate)
import Test.HUnit.Base  ((~?=), Test(TestCase, TestList))
import Test.HUnit.Text (runTestTT)
import Test.HUnit.Tools (assertRaises)

pos :: Int -> Int
pos x
   | x >= 0 = x
   | otherwise = error "Invalid Input"

instance Eq ErrorCall where
    x == y = (show x) == (show y)

assertError msg ex f = 
    TestCase $ assertRaises msg (ErrorCall ex) $ evaluate f

tests = TestList [
  (pos 0) ~?= 0
  , (pos 1) ~?= 1
  , assertError "Negative argument raises an error" "Invalid Input" (pos (-1))
  ]   

main = runTestTT tests

关于unit-testing - 如何测试 Haskell 中的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13350164/

相关文章:

python - 如何访问pytest中的整体运行时?

haskell - 如何将 HUnit 添加到 Yesod 项目

haskell - 无法为包含 UTCTime 的数据派生 Show 实例

c# - 使用 Moq 查看是否使用值调用了方法

php - UnitTest 对象模拟或真实对象

c# - 将单元测试添加到不是为它设计的代码

encoding - 如何在Windows上安装Haskell模块encoding-0.6.3?

java - 如何使用未实现 `equals` 的参数模拟方法调用?

reactjs - 如何测试解决 promise 然后在 React 中更改状态的方法?

php - 在 PhpUnit 中测试 token 过期的正确方法