如何在F#中编写异步单元测试方法

Sco*_*rod 5 f# unit-testing async-await

如何在F#中编写异步测试方法?

我引用以下代码

[TestMethod]
public async Task CorrectlyFailingTest()
{
  await SystemUnderTest.FailAsync();
}
Run Code Online (Sandbox Code Playgroud)

这是我失败的尝试:

[<Test>]
let ``Correctly failing test``() = async {

        SystemUnderTest.FailAsync() | Async.RunSynchronously
    }
Run Code Online (Sandbox Code Playgroud)

Ter*_*nce 6

因此,经过一些研究,事实证明这比应该的要困难得多。https://github.com/nunit/nunit/issues/34

话虽如此,但提到了一种解决方法。这似乎有点蹩脚,但是,它看起来像是在外部将任务委托声明为成员并利用它是一种可行的解决方法。

线程中提到的示例:

open System.Threading.Tasks
open System.Runtime.CompilerServices

let toTask computation : Task = Async.StartAsTask computation :> _

[<Test>]
[<AsyncStateMachine(typeof<Task>)>]
member x.``Test``() = toTask <| async {
    do! asyncStuff()
}
Run Code Online (Sandbox Code Playgroud)

open System.Threading.Tasks
open NUnit.Framework

let toAsyncTestDelegate computation = 
    new AsyncTestDelegate(fun () -> Async.StartAsTask computation :> Task)

[<Test>]
member x.``TestWithNUnit``() = 
    Assert.ThrowsAsync<InvalidOperationException>(asyncStuff 123 |> toAsyncTestDelegate)
    |> ignore

[<Test>]
member x.``TestWithFsUnit``() = 
    asyncStuff 123 
    |> toAsyncTestDelegate
    |> should throw typeof<InvalidOperationException>
Run Code Online (Sandbox Code Playgroud)

XUnit 也有类似的问题,并提出了解决方案:https : //github.com/xunit/xunit/issues/955

所以你应该能够在 xunit 中做到这一点

[<Fact>]
let ``my async test``() =
  async {
    let! x = someAsyncCall()
    AssertOnX
  }
Run Code Online (Sandbox Code Playgroud)

对不起,如果这不是最令人满意的答案。