2

我正在使用 MSTest 在 F# 中编写单元测试,并且我想编写断言引发异常的测试。我可以找到的两种方法是 (1) 用 C# 编写测试或 (2) 不使用 MSTest,或者在其上添加另一个测试包,如 xunit。这些都不是我的选择。我唯一能在这方面找到的是MSDN文档,但它省略了 F# 示例。

使用 F# 和 MSTest,我如何断言特定调用引发特定异常?

4

2 回答 2

3

MSTest 有一个ExpectedExceptionAttribute可以使用的方法,但它不是测试已抛出异常的理想方法,因为它不允许您断言应该抛出的特定调用。如果测试方法中的任何方法抛出预期的异常类型,则测试通过。这对于常用的异常类型(如InvalidOperationException. 我经常使用 MSTest,我们在自己的类(在 C# 中)中有一个Throws辅助方法。AssertHelperF# 将允许您将其放入Assert模块中,以便它与 intellisense 中的所有其他 Assert 方法一起出现,这非常酷:

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)
于 2013-09-24T21:18:16.640 回答
1

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
于 2013-09-24T18:34:37.230 回答