MSTest has an ExpectedExceptionAttribute
that can be used, but it is a less than ideal way to test an exception has been thrown because it doesn't let you assert the specific call that should throw. If any method in the test method throws the expected exception type, then the test passes. This can be bad with commonly used exception types like InvalidOperationException
. I use MSTest a lot and we have a Throws
helper method for this in our own AssertHelper
class (in C#). F# will let you put it into an Assert
module so that it appears with all the other Assert methods in intellisense, which is pretty cool:
namespace FSharpTestSpike
open System
open Microsoft.VisualStudio.TestTools.UnitTesting
module Assert =
let Throws<'a> f =
let mutable wasThrown = false
try
f()
with
| ex -> Assert.AreEqual(ex.GetType(), typedefof<'a>, (sprintf "Actual Exception: %A" ex)); wasThrown <- true
Assert.IsTrue(wasThrown, "No exception thrown")
[<TestClass>]
type MyTestClass() =
[<TestMethod>]
member this.``Expects an exception and thrown``() =
Assert.Throws<InvalidOperationException> (fun () -> InvalidOperationException() |> raise)
[<TestMethod>]
member this.``Expects an exception and not thrown``() =
Assert.Throws<InvalidOperationException> (fun () -> ())
[<TestMethod>]
member this.``Expects an InvalidOperationException and a different one is thrown``() =
Assert.Throws<InvalidOperationException> (fun () -> Exception("BOOM!") |> raise)