I have a function that reads JSON from a file:
(define (extract-directives filename #:file-input [with-input-from-file with-input-from-file])
(define ignore (with-handlers ([exn:fail:filesystem? (lambda (exn) (ignore null (hasheq) (hasheq)))])
(with-input-from-file filename
(lambda () (read-json))))))
NB I've chopped some of the function out for brevity.
Now what I want to do is use a mock to raise an exception as if the file can't be found:
(module+ test
(define test-settings (hash 'ignore-file "settings.json"))
(test-case "extract-directives returns an empty hash if the file can't be read"
(define mock-file-read (mock #:behavior (const (raise (exn:fail:filesystem:exists "test" (current-continuation-marks))))))
(define result (extract-directives test-settings #:file-input mock-file-read))
(check-true (hash-empty? result)))
However, instead of the flow of control, I'm expecting (i.e. the mock raises an exception then with-handlers catches it) I get:
extract-directives returns an empty hash if the file can't be read
; ERROR
test
So I'm confused about how best to simulate errors without handing bad data to the function. How can I do this better?