# Rackunit: test-case makes testing higher-order functions with exception handlers behave oddly

**URL:** <https://racket.discourse.group/t/rackunit-test-case-makes-testing-higher-order-functions-with-exception-handlers-behave-oddly/3467>\
**Category:** General\
**Created:** [January 5, 2025, 4:08pm UTC](https://racket.discourse.group/t/rackunit-test-case-makes-testing-higher-order-functions-with-exception-handlers-behave-oddly/3467 "2025-01-05T16:08:13Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [January 5, 2025, 4:08pm UTC](https://racket.discourse.group/t/rackunit-test-case-makes-testing-higher-order-functions-with-exception-handlers-behave-oddly/3467/1 "2025-01-05T16:08:13Z")

</div>

There's a good chance I'm "holding it wrong," so someone please point out where I've missed things.

I have a test that looks like this:

```scheme
(define (f g)
  (with-handlers ([exn:fail? (lambda (e)
                               (displayln (exn-message e))
                               e)])
    (g)))
(define result (f (lambda ()
                    (check-equal? 1 2)
                    123)))
(check-equal? result 123))

```

Output is

```scheme
--------------------
FAILURE [,bt for context]
name: check-equal?
location: string:5:21
actual: 1
expected: 2
--------------------

```

Now, if I change to `test-case`:

```scheme
(test-case "f"
  (define result (f (lambda ()
                      (check-equal? 1 2)
                      123)))
  (check-equal? result 123))

```

I instead get

```scheme
--------------------
f
FAILURE [,bt for context]
name: check-equal?
location: string:6:1
actual: (exn:test:check "" #<continuation-mark-set> ...)
expected: 123
--------------------

```

Notice that the `check-equal?` failure has been swallowed. I managed to pin this down to an odd interaction between `test-case` and `current-check-around`: the former sets the latter to `plain-check-around` during the execution of the entire test case body, but still invokes `current-test-around` (presumably this is what enables that early exit behavior when a check fails within a test case). Indeed, only while writing this did I even notice that we have both `current-check-around` and `current-test-around`! I (mistakenly) assumed `test-case` was using `current-check-around` for a long time because of the comment on `check-around`:

```scheme
;; Like default-check-around, except without test logging. This used to be used
;; by test-case, and is currently undocumented. […]
;; Setting (current-check-handler) to `raise` makes this equivalent to
;; plain-check-around.

```

Anyway, there's an ugly workaround for testing higher-order functions that have their own exception handlers:

```scheme
(let ([default (current-check-around)])
  (test-case "f"
    (define result (f (lambda ()
                        (parameterize ([current-check-around default])
                          (check-equal? 1 2)
                          123))))
    (check-equal? result 123)))

```

This does have the side effect that checks within the `parameterize` do not stop execution of the test case!

(In my real example, I'm going to wrap the parameterize in a function to be called inside the higher-order function, possibly as a macro. Naming it is difficult, though.)
