# Raising exceptions in mocks

**URL:** <https://racket.discourse.group/t/raising-exceptions-in-mocks/775>\
**Category:** Questions & Answers\
**Tags:** question\
**Created:** [March 8, 2022, 3:51am UTC](https://racket.discourse.group/t/raising-exceptions-in-mocks/775 "2022-03-08T03:51:03Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![robertpostill](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/robertpostill/32/53_2.png) [@robertpostill](https://racket.discourse.group/u/robertpostill)\
**Post date:** [March 8, 2022, 3:51am UTC](https://racket.discourse.group/t/raising-exceptions-in-mocks/775/1 "2022-03-08T03:51:03Z")

</div>

I have a function that reads JSON from a file:

```scheme
(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:

```scheme
(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:

```scheme
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?

---

<div class="post-metadata">

**Author:** ![sorawee](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sorawee](https://racket.discourse.group/u/sorawee)\
**Post date:** [March 8, 2022, 4:18am UTC](https://racket.discourse.group/t/raising-exceptions-in-mocks/775/2 "2022-03-08T04:18:56Z")

</div>

The error occurs here:

```scheme
(define mock-file-read (mock #:behavior (const (raise (exn:fail:filesystem:exists "test" (current-continuation-marks))))))

```

`const` is a regular function, so in the function application `(const (raise ...))`, `(raise ...)` is evaluated, causing the exception right away.

To control the evaluation order so that `(raise ...)` is delayed until called, you could either write an explicit lambda:

```scheme
(mock #:behavior (lambda (_dummy) (raise ...)))

```

or use the macro `thunk*`.

```scheme
(mock #:behavior (thunk* (raise ...)))

```

---

<div class="post-metadata">

**Author:** ![robertpostill](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/robertpostill/32/53_2.png) [@robertpostill](https://racket.discourse.group/u/robertpostill)\
**Post date:** [March 9, 2022, 12:02am UTC](https://racket.discourse.group/t/raising-exceptions-in-mocks/775/3 "2022-03-09T00:02:25Z")

</div>

Ah, that makes sense. It had not occurred to me that const would be immediately evaluated. But yes thunk\* works the way I need it to.

Thanks for your help.
