I've got a function:
unify :: [Constraint] -> [Substitution]
and in certain cases it throws exceptions with the error
function:
error "Circular constraint"
I'm using Test.HUnit
for unit testing and I'd like to make a test case that asserts these errors are thrown on certain inputs. I found this , which provides a way of testing for exceptions that are instances of Eq
, but error
seems to give an ErrorCall
exception , which is not an instance of Eq
, so I get the error:
No instance for (Eq ErrorCall)
arising from a use of `assertException'
How can I write a TestCase
that asserts that error
was called and (preferably) checks the message?
Ideally I'd refactor your function into
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'
I would then test unify'
instead of testing unify
.
If there was more than one possible error message, I would refactor it like this instead:
unify' :: [Constraint] -> Either String [Substitution]
-- and return Left foo instead of calling error foo
unify = either error id . unify'
(Incidentally, if this is for a library other programmers will be using, some of them would prefer to call unify'
instead of the partial function unify
.)
If you can't refactor your code, I'd modify the code you link to, replacing assertException
with:
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.