I am taking my first steps with exception handling in Racket and would like to write a unit test, which checks, if a procedure raises an exception for a specific input.
The following is what I already have:
The procedure, which shall raise the exception:
(define (div-interval x y)
;; EXERCISE 2.10
; exception handling
(with-handlers
([exn:fail:contract:divide-by-zero?
(lambda (exn)
(displayln (exn-message exn))
#f)])
(if (or
(>= (upper-bound y) 0)
(<= (lower-bound y) 0))
(raise
(make-exn:fail:contract:divide-by-zero
"possible division by zero, interval spans zero"
(current-continuation-marks)))
(mul-interval
x
(make-interval
(/ 1.0 (upper-bound y))
(/ 1.0 (lower-bound y)))))))
The unit test:
(require rackunit)
(define exercise-test
(test-suite
"exercise test suite"
#:before (lambda () (begin (display "before")(newline)))
#:after (lambda () (begin (display "after")(newline)))
(test-case
"checking interval including zero"
(check-exn
exn:fail:contract:divide-by-zero?
(div-interval
(make-interval 1.0 2.0)
(make-interval -3.0 2.0))
"Exception: interval spans zero, possible division by zero")))
(run-test exercise-test)
There are some more tests in this test suite, but they are for other procedures, so I did not include them in this code. When I run my program, I get the following output:
before
possible division by zero, interval spans zero
after
'(#<test-success> #<test-success> #<test-success> #<test-success> #<test-error>)
Where the <test-error>
is for the test case in this post.
It seems the procedure does not raise the exception.
Is this, because I have a handler
in my procedure, which returns #f
and thus already "ate" the exception?
How would I usually write a unit test for raised exceptions?
lambda
expression, in order to not evaluate the division immediately, but make it a function for it to be called inside thecheck-exn
? – Footwork