基于 SO 问题 13350164如何测试 Haskell 中的错误?,我正在尝试编写一个单元测试,它断言给定无效输入,递归函数会引发异常。我采用的方法适用于非递归函数(或者当第一次调用引发异常时),但是一旦异常发生在调用链的更深处,断言就会失败。
我已经阅读了问题 6537766 Haskell 错误处理方法的优秀答案,但不幸的是,对于我的学习曲线的这一点来说,这个建议有点太笼统了。我的猜测是这里的问题与惰性评估和非纯测试代码有关,但我希望能得到专家的解释。
Maybe
在这种情况下(例如或),我是否应该采用不同的方法来处理错误Either
,或者是否有合理的修复方法可以在使用这种风格时使测试用例正常工作?
这是我想出的代码。前两个测试用例成功,但第三个测试用例失败"Received no exception, but was expecting exception: Negative item"
。
import Control.Exception (ErrorCall(ErrorCall), evaluate)
import Test.HUnit.Base ((~?=), Test(TestCase, TestList))
import Test.HUnit.Text (runTestTT)
import Test.HUnit.Tools (assertRaises)
sumPositiveInts :: [Int] -> Int
sumPositiveInts [] = error "Empty list"
sumPositiveInts (x:[]) = x
sumPositiveInts (x:xs) | x >= 0 = x + sumPositiveInts xs
| otherwise = error "Negative item"
instance Eq ErrorCall where
x == y = (show x) == (show y)
assertError msg ex f =
TestCase $ assertRaises msg (ErrorCall ex) $ evaluate f
tests = TestList [
assertError "Empty" "Empty list" (sumPositiveInts ([]))
, assertError "Negative head" "Negative item" (sumPositiveInts ([-1, -1]))
, assertError "Negative second item" "Negative item" (sumPositiveInts ([1, -1]))
]
main = runTestTT tests