Reputation: 23
I'm writing unit tests in F# using MSTest, and I'd like to write tests that assert that an exception is raised. The two methods that I can find for doing this are either (1) write the tests in C# or (2) don't use MSTest, or add another test package, like xunit, on top of it. Neither of these is an option for me. The only thing I can find on this is in the MSDN docs, but that omits F# examples.
Using F# and MSTest, how do I assert that a particular call raises a particular exception?
Upvotes: 2
Views: 626
Reputation: 40818
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)
Upvotes: 2
Reputation: 2831
Like this?
namespace Tests
open Microsoft.VisualStudio.TestTools.UnitTesting
open System
[<TestClass>]
type SomeTests () =
[<TestMethod; ExpectedException (typeof<InvalidOperationException>)>]
member this.``Test that expects InvalidOperationException`` () =
InvalidOperationException () |> raise |> ignore
Upvotes: 1