Reputation: 487
I am learning Haskell and I want to do TDD. I am trying to test if a function raise an expected exception. I am using HUnit and testpack.
testpack provides an assertRaises function but I don't manage to compile my code :(
Here is my source code :
module Main where
import Test.HUnit
import Test.HUnit.Tools
import Control.Exception
foo n | n > 2 = throw ( IndexOutOfBounds ( "Index out of bounds : " ++ ( show n ) ) )
foo n | otherwise = n
testException = TestCase( assertRaises "throw exception" ( IndexOutOfBounds "Index out of bounds : 4" ) ( foo 4 ) )
main = runTestTT ( TestList [ testException ] )
When I compile it with ghc I get the following error message :
test_exceptions.hs:10:107:
No instance for (Ord (IO a0))
arising from a use of `foo'
Possible fix: add an instance declaration for (Ord (IO a0))
In the third argument of `assertRaises', namely `(foo 4)'
In the first argument of `TestCase', namely
`(assertRaises
"throw exception"
(IndexOutOfBounds "Index out of bounds : 4")
(foo 4))'
In the expression:
TestCase
(assertRaises
"throw exception"
(IndexOutOfBounds "Index out of bounds : 4")
(foo 4))
test_exceptions.hs:10:111:
No instance for (Num (IO a0))
arising from the literal `4'
Possible fix: add an instance declaration for (Num (IO a0))
In the first argument of `foo', namely `4'
In the third argument of `assertRaises', namely `(foo 4)'
In the first argument of `TestCase', namely
`(assertRaises
"throw exception"
(IndexOutOfBounds "Index out of bounds : 4")
(foo 4))'
What's wrong ?
Upvotes: 2
Views: 361
Reputation: 47042
assertRaises
expects its third argument to be an IO action (with type IO a
), but the return type from foo
is a number (with type (Num a, Ord a) => a
), not an IO action.
Try replacing (foo 4)
with (evaluate (foo 4))
.
Upvotes: 3