Home > Enterprise >  How to assert that a function throws an exception?
How to assert that a function throws an exception?

Time:01-20

I can catch exceptions:

try some_fn () with | e -> print_endline "exception caught!"

but what about the other way around, detecting that a function does not throw an exception (when it should)?

CodePudding user response:

I managed to write some very hacky way to achieve that: I create a wrapper around the function I want to test, which throws some specific exception at the end. I catch anything but that exception.

exception Finished

let check (fn : unit -> unit) =
  let wrapper _ = (
    fn ();
    raise Finished)
  in
  try wrapper () with e when e <> Finished -> ()

in utop this works:

utop # check (fun _ -> ());;
Exception: Finished.
utop # check (fun _ -> failwith "hey");;
- : unit = ()

EDIT: my coworker suggested:

let should_fail fn =
  if Result.try_with fn |> Result.is_ok then failwith "this test should fail"

CodePudding user response:

Exceptions can be handled within pattern matching cases, allowing very clean expression for this check:

match some_fn () with 
| exception _ -> print_endline "exception caught!"
| _           -> print_endline "error: no exception raised!"

We can abstract this check into a function:

let throws_exception f =
  match f () with 
  | exception _ -> true
  | _           -> false

Which we can use in an assertion like so:

assert (throws_exception (fun () -> raise (Failure "msg")))
  • Related