I'm on a Mac running F# using .NET Core 2.0.
I have a function that looks like this:
let rec evaluate(x: string) =
match x with
// ... cases
| _ -> failwith "illogical"
I'd like to write an Expecto test that validates that the exception is thrown as expected, something along the lines of:
// doesn't compile
testCase "non-logic" <| fun _ ->
Expect.throws (evaluate "Kirkspeak") "illogical"
The error is
This expression was expected to have type 'unit -> unit' but here has type 'char'
unit -> unit
makes me this is analogous to Assert.Fail
, which is not what I want.
Being somewhat new to F# and Expecto, I'm having trouble locating a working example of asserting that an exception is thrown as expected. Does anyone have one?
Expect.throws
has the signature (unit -> unit) -> string -> unit
so the function you want to test must be (unit -> unit) or be wrapped inside a function that is (unit -> unit).
let rec evaluate (x: string) : char =
match x with
// ... cases
| _ -> failwith "illogical"
The compiler error is telling you that the function you passed to Expect.throws does not have the right signature yet.
[<Tests>]
let tests = testList "samples" [
test "non-logic" {
// (evaluate "Kirkspeak") is (string -> char)
// but expecto wants (unit -> unit)
Expect.throws (evaluate "Kirkspeak") "illogical"
}
]
[<EntryPoint>]
let main argv =
Tests.runTestsInAssembly defaultConfig argv
One way to make it work is to change
Expect.throws (evaluate "Kirkspeak") "illogical"
to
// you could instead do (fun () -> ...)
// but one use of _ as a parameter is for when you don't care about the argument
// the compiler will infer _ to be unit
Expect.throws (fun _ -> evaluate "Kirkspeak" |> ignore) "illogical"
Now expecto is happy!
This answer was the way I thought through it. It is usually helpful to follow the type signatures.
EDIT: I saw your error message saying This expression was expected to have type 'unit -> unit' but here has type 'char'
so I updated my answer to match it.