测试F#异步工作流时如何获取有用的堆栈跟踪

最大值

我想测试以下异步工作流程(使用NUnit + FsUnit):

let foo = async {
  failwith "oops"
  return 42
}

我为此编写了以下测试:

let [<Test>] TestFoo () =
  foo
  |> Async.RunSynchronously
  |> should equal 42

由于foo引发,因此在单元测试运行器中得到以下堆栈跟踪:

System.Exception : oops
   at Microsoft.FSharp.Control.CancellationTokenOps.RunSynchronously(CancellationToken token, FSharpAsync`1 computation, FSharpOption`1 timeout)
   at Microsoft.FSharp.Control.FSharpAsync.RunSynchronously(FSharpAsync`1 computation, FSharpOption`1 timeout, FSharpOption`1 cancellationToken)
   at ExplorationTests.TestFoo() in ExplorationTests.fs: line 76

不幸的是,stacktrace并没有告诉我引发异常的位置。它在RunSynchronously停止。

我在某处听说Async.Catch神奇地恢复了堆栈跟踪,所以我调整了测试:

let [<Test>] TestFooWithBetterStacktrace () =
  foo
  |> Async.Catch
  |> Async.RunSynchronously
  |> fun x -> match x with 
              | Choice1Of2 x -> x |> should equal 42
              | Choice2Of2 ex -> raise (new System.Exception(null, ex))

现在这很丑陋,但至少会产生有用的堆栈跟踪:

System.Exception : Exception of type 'System.Exception' was thrown.
  ----> System.Exception : oops
   at Microsoft.FSharp.Core.Operators.Raise(Exception exn)
   at ExplorationTests.TestFooWithBetterStacktrace() in ExplorationTests.fs: line 86
--Exception
   at Microsoft.FSharp.Core.Operators.FailWith(String message)
   at [email protected](Unit unitVar) in ExplorationTests.fs: line 71
   at [email protected](AsyncParams`1 args)

这次,堆栈跟踪将准确显示错误发生的位置:ExplorationTests.foo@line 71

有没有办法摆脱Async.Catch和两个选择之间的匹配,同时仍然获得有用的堆栈跟踪?有没有更好的方法来构造异步工作流测试?

最大值

由于Async.Catch和重新抛出异常似乎是获得有用的堆栈跟踪的唯一方法,所以我提出了以下内容:

type Async with
  static member Rethrow x =
    match x with 
      | Choice1Of2 x -> x
      | Choice2Of2 ex -> ExceptionDispatchInfo.Capture(ex).Throw()
                         failwith "nothing to return, but will never get here"

注意“ ExceptionDispatchInfo.Capture(ex).Throw()”。这是一个最好的方法,可以在不破坏其堆栈跟踪的情况下抛出异常(缺点:仅自.NET 4.5起可用)。

现在,我可以像这样重写测试“ TestFooWithBetterStacktrace”:

let [<Test>] TestFooWithBetterStacktrace () =
  foo
  |> Async.Catch
  |> Async.RunSynchronously
  |> Async.Rethrow
  |> should equal 42

测试看起来好多了,重新抛出的代码没有发生错误(和以前一样),并且当出现问题时,我在测试运行程序中获得了有用的堆栈跟踪信息。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

具有超时的F#异步工作流

来自分类Dev

使用xUnit.net的任务支持测试F#异步工作流

来自分类Dev

jBPM 是否有用于异步工作流的固定大小线程池?

来自分类Dev

单元测试后,如何在工作流跟踪中声明活动计数?

来自分类Dev

调用F#异步工作流程时,是否可以避免定义临时标签?

来自分类Dev

如何获取完整的堆栈跟踪以执行异步

来自分类Dev

基于Python的异步工作流模块:celery工作流和luigi工作流有什么区别?

来自分类Dev

异步工作流程的F#问题,并尝试/使用

来自分类Dev

使用异步代码时获取有意义的堆栈跟踪

来自分类Dev

如何在工作流表单中获取工作流实例的 id?

来自分类Dev

如何使用自定义工作流步骤查找所有工作流

来自分类Dev

F#计算堆栈的无限总和时获取堆栈溢出

来自分类Dev

测试REST API模块时获取人类可读的堆栈跟踪

来自分类Dev

链接多个并行异步工作流

来自分类Dev

共享记录时如何执行CRM工作流

来自分类Dev

是否存在具有用户定义状态的Ruby on Rails工作流gem?

来自分类Dev

是否有用于注册/识别 Pandas 数据分析工作流模式的包?

来自分类Dev

测试和部署工作流(Rails)

来自分类Dev

在F#工作流程中运行C#异步方法

来自分类Dev

在OpenERP 7中按下按钮时,如何在工作流状态下获取日期?

来自分类Dev

实时工作流的自定义工作流活动中缺少跟踪日志

来自分类Dev

获取工作流任务Alfresco的NodeRef

来自分类Dev

如何在异步工作流中使用Async.Parallel?

来自分类Dev

启动新的工作流程实例时,如何获取我的工作流程RunID?

来自分类Dev

Webpack 2 工作流如何测试我的生产文件以及如何上传?

来自分类Dev

Accurev:如何从流中获取所有用户的列表?

来自分类Dev

Accurev:如何从流中获取所有用户的列表?

来自分类Dev

所有 AngularJS 运行时错误都参考 angular.js - 没有有用的堆栈跟踪

来自分类Dev

如何获取指定工作流程的所有过渡

Related 相关文章

  1. 1

    具有超时的F#异步工作流

  2. 2

    使用xUnit.net的任务支持测试F#异步工作流

  3. 3

    jBPM 是否有用于异步工作流的固定大小线程池?

  4. 4

    单元测试后,如何在工作流跟踪中声明活动计数?

  5. 5

    调用F#异步工作流程时,是否可以避免定义临时标签?

  6. 6

    如何获取完整的堆栈跟踪以执行异步

  7. 7

    基于Python的异步工作流模块:celery工作流和luigi工作流有什么区别?

  8. 8

    异步工作流程的F#问题,并尝试/使用

  9. 9

    使用异步代码时获取有意义的堆栈跟踪

  10. 10

    如何在工作流表单中获取工作流实例的 id?

  11. 11

    如何使用自定义工作流步骤查找所有工作流

  12. 12

    F#计算堆栈的无限总和时获取堆栈溢出

  13. 13

    测试REST API模块时获取人类可读的堆栈跟踪

  14. 14

    链接多个并行异步工作流

  15. 15

    共享记录时如何执行CRM工作流

  16. 16

    是否存在具有用户定义状态的Ruby on Rails工作流gem?

  17. 17

    是否有用于注册/识别 Pandas 数据分析工作流模式的包?

  18. 18

    测试和部署工作流(Rails)

  19. 19

    在F#工作流程中运行C#异步方法

  20. 20

    在OpenERP 7中按下按钮时,如何在工作流状态下获取日期?

  21. 21

    实时工作流的自定义工作流活动中缺少跟踪日志

  22. 22

    获取工作流任务Alfresco的NodeRef

  23. 23

    如何在异步工作流中使用Async.Parallel?

  24. 24

    启动新的工作流程实例时,如何获取我的工作流程RunID?

  25. 25

    Webpack 2 工作流如何测试我的生产文件以及如何上传?

  26. 26

    Accurev:如何从流中获取所有用户的列表?

  27. 27

    Accurev:如何从流中获取所有用户的列表?

  28. 28

    所有 AngularJS 运行时错误都参考 angular.js - 没有有用的堆栈跟踪

  29. 29

    如何获取指定工作流程的所有过渡

热门标签

归档