简体   繁体   English

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

[英]How do I write an async unit test method in F#

How do I write an async test method in F#?如何在 F# 中编写异步测试方法?

I'm referencing the following code :我正在引用以下代码

[TestMethod]
public async Task CorrectlyFailingTest()
{
  await SystemUnderTest.FailAsync();
}

This is my failed attempt:这是我失败的尝试:

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

        SystemUnderTest.FailAsync() | Async.RunSynchronously
    }

So after a bit of research, it turns out that this is more difficult than it ought to be.因此,经过一些研究,事实证明这比应该的要困难得多。 https://github.com/nunit/nunit/issues/34 https://github.com/nunit/nunit/issues/34

That being said a workaround was mentioned.话虽如此,但提到了一种解决方法。 This seems kinda lame but, it looks like declaring a task delegate outside as a member and leveraging it is a viable work around.这似乎有点蹩脚,但是,它看起来像是在外部将任务委托声明为成员并利用它是一种可行的解决方法。

The examples mentioned in the thread:线程中提到的示例:

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()
}

And

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>

XUnit had a similar problem and did come up with a solution: https://github.com/xunit/xunit/issues/955 XUnit 也有类似的问题,并提出了解决方案: https : //github.com/xunit/xunit/issues/955

So you should be able to do this in xunit所以你应该能够在 xunit 中做到这一点

[<Fact>]
let ``my async test``() =
  async {
    let! x = someAsyncCall()
    AssertOnX
  }

Sorry if this is not the most satisfying answer.对不起,如果这不是最令人满意的答案。

open Xunit

[<Fact>]
let ``my async test``() =
  async {
    do! Async.AwaitTask(someAsyncCall())|> Async.Ignore
    AssertOnX
  }

I asked https://github.com/fsprojects/FsUnit/issues/153 because I think that it is a responsibility of the F# unit testing framework to provide a right binding.我询问了https://github.com/fsprojects/FsUnit/issues/153,因为我认为 F# 单元测试框架有责任提供正确的绑定。 Meanwhile, this looks the best for me.同时,这对我来说是最好的。

    open System.Threading.Tasks

    let runAsyncTest async = async |> Async.StartImmediateAsTask :> Task

    [<Test>]
    let ``Some test`` () = runAsyncTest <| async {
    }

This is an old question but now can use the task builder from the Ply package for testing C# async methods in Xunit like so:这是一个老问题,但现在可以使用Ply包中的task构建器来测试 Xunit 中的 C# 异步方法,如下所示:

    open FSharp.Control.Tasks
    open System.Threading
    open Xunit
    
    let ``Test some Task returning async method`` () =
        task {
            let! actual = MyType.GetSomethingAsync()
            Assert.Equal(expected, actual)
            
            return ()
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM