代码之家  ›  专栏  ›  技术社区  ›  reckface

如何在F#中对异步方法进行单元测试?

  •  1
  • reckface  · 技术社区  · 6 年前

    我有一个方法,它返回一个我试图在F#中同步测试的任务。 下面是一个方法,它是一个C#接口的实现:

    member this.RunAsync(): System.Threading.Tasks.Task =             
        async{
            this._settings.LogSettings |> Seq.iter(fun settings -> this.clearLogs(settings)) |> ignore
            return ()
            } |> Async.StartAsTask :> _
    

    Async.AwaitTask(logFileManager.RunAsync())|> Async.Ignore
    // and I've tried
    async {
      logFileManager.RunAsync() 
      Assert.Pass()
    } |> Async.RunSynchronously
    

    测试运行时,如果有5项,预期的调用数应该是5,但是测试失败,调用的随机数介于1和2之间。

    对于另一个实现,C#中的相同测试只是:

    [Test]
    public async Task Should_do_something_in_an_asynchronous_method()
    {
        var unitUnderTest = GetService();
        await unitUnderTest.RunAsync();
    }
    

    如何确保完成单元测试的任务?

    我如何编写等效的测试方法 async

    1 回复  |  直到 6 年前
        1
  •  5
  •   Fyodor Soikin    6 年前

    看一看 await 在你的C#代码中输入单词。你认为它有什么作用?如果你把它掉了怎么办?测试还能用吗?

    不会的,因为打电话给 RunAsync

    这正是你在F#代码中所做的:你只是调用函数并忘记它,而不是让它成为周围工作流程的一部分。该函数自行关闭并开始工作,您的 async

    在F#中,使嵌套调用成为周围流的一部分的方法是 let! do! 关键字,有点类似于 等候 在C#中。这样地:

    let f = async { ... }
    let g = async {
        let! x = f
        printfn "f returned: %A" x
    }
    

    运行异步 返回一个C# Task Async Async.AwaitTask 功能:

    async {
      do! logFileManager.RunAsync() |> Async.AwaitTask
      Assert.Pass()
    } |> Async.RunSynchronously