Search code examples
unit-testingexceptionlisprackethtdp

How to use RackUnit to check for an error?


I have the following Racket code.

#lang racket

(require rackunit racket/exn)

(define (string-last s)
  (let ((lng (string-length s)))
    (substring s (- lng 1) lng)))

(string-last "")
(check-equal? (string-last "1") "1")
(check-equal? (string-last "testing") "g")

The call of string last with an empty string fails as expected with:

--------------------
. ERROR
name:       check-exn
location:   014.rkt:12:0

substring: contract violation
  expected: exact-nonnegative-integer?
  given: -1
  argument position: 2nd
  other arguments...:
   ""
   0
--------------------

How to check for the error by using RackUnit library?

I tried

(check-exn exn:fail? (string-last ""))

and several other variants in place of exn:fail? but I didn't manage to find the right one.


Solution

  • check-exn needs a function of no arguments – a thunk – it can call which should raise the exception. So the right incantation would be

    (check-exn exn:fail? (thunk (string-last "")))
    

    It must be passed a thunk because otherwise the default evaluation order of Racket would mean that the exception is raised before the function is called, so it never gets to catch it.