Haskell 单元测试在 HUnit 中的错误调用



我有一个函数:

unify :: [Constraint] -> [Substitution]

在某些情况下,它会使用 error 函数引发异常:

error "Circular constraint"

我正在使用Test.HUnit进行单元测试,我想创建一个测试用例,断言这些错误在某些输入上抛出。我发现了这个,它提供了一种测试Eq实例的异常的方法,但error似乎给出了一个ErrorCall异常,这不是Eq的实例,所以我得到错误:

No instance for (Eq ErrorCall)
  arising from a use of `assertException'

如何编写断言error被调用并(最好)检查消息的TestCase

理想情况下,我会将您的函数重构为

unify' :: [Constraint] -> Maybe [Substitution]
unify' = -- your original function, but return Nothing instead of calling error,
         -- and return Just x when your original function would return x
unify = fromMaybe (error "Circular constraint") . unify'

然后我会测试unify'而不是测试unify.

如果有多个可能的错误消息,我会像这样重构它:

unify' :: [Constraint] -> Either String [Substitution]
    -- and return Left foo instead of calling error foo
unify = either error id . unify'

(顺便说一下,如果这是针对其他程序员将使用的库,他们中的一些人更喜欢调用unify'而不是偏部函数unify


如果你无法重构你的代码,我会修改你链接到的代码,assertException替换为:

assertErrorCall :: String -> IO a -> IO ()
assertErrorCall desiredErrorMessage action
    = handleJust isWanted (const $ return ()) $ do
        action
        assertFailure $ "Expected exception: " ++ desiredErrorMessage
  where isWanted (ErrorCall actualErrorMessage)
            = guard $ actualErrorMessage == desiredErrorMessage

相关内容

  • 没有找到相关文章

最新更新