I am implementing "smart" constructor performing runtime checking as described here https://wiki.haskell.org/Smart_constructors#Smart.28er.29_constructors
My first question is : how to unit test that invalid argument throws ?
Here is what I have tried
import Control.Exception
import Test.HUnit
metalResistor :: Bands -> Resistor
metalResistor n = Control.Exception.assert (n >= 4 && n <= 8) $ Metal n
m0 = metalResistor 0
test1 = TestCase ( assertBool (show mo) False)
tests = TestList [TestLabel "test1" test1]
Results is
*Main> runTestTT tests
### Error in: 0:test1
Assertion failed
CallStack (from HasCallStack):
assert, called at test.hs:42:19 in main:Main
Cases: 1 Tried: 1 Errors: 1 Failures: 0
Counts {cases = 1, tried = 1, errors = 1, failures = 0}
My expectation is to catch the exception in the unit test (assertThrow ?) and that the test succeed.
My second question is maybe more opinion base, but I am unsure which approach to take for smart constructor : the one with error or the one with Conntrol.Exception.assert
In the long run, I feel better to use the error solution ; for sake of clarity and for code maintenance and bug tracking, plus that tedious to write one time is better that tedious to read 1000 times.