猿问

当在银杏执行 defer func 时

我正在用 ginkgo 重写我们的 k8s 控制器的单元测试。


与之前的 TDD 一样,对于每个测试,我们都会有类似的东西。


    // Create the Channel  object and expect the Reconcile

    g.Expect(c.Create(context.TODO(), myObj)).NotTo(gomega.HaveOccurred())

    defer c.Delete(context.TODO(),myObj)

我们想要的是,为测试创建一个对象,并在此测试后将其从下划线集群中删除。


现在,ginkgo我们正在spec容器内运行测试。对我来说,这container是原始过程,如果是这种情况,是否意味着规范中defer定义的将在退出而不是退出规范It之前执行。containerIt


例如,


var _ = Describe("my desr", func(){

   It("a", func(){

     fmt.Println(100)

     defer func(){fmt.Println("a", 100)}()

   })


   It("b", func(){

     fmt.Println(200)

     defer func(){fmt.Println("b", 200)}()

  })

})

结果会是:


一种


100

a100

200

b200

或者


b


100

200

b200

a100

就我而言,我绝对是第一个行为。或者我在获得defer行为方面的方向是错误的?我的意思是,我应该研究BeforeEachandAfterEach方法吗?


慕侠2389804
浏览 155回答 3
3回答

幕布斯7119047

您会看到第一个行为,因为 s 的封闭范围与之前的defers 是相同的匿名函数Println。defer退出范围时调用红色函数。

汪汪一只猫

“起源过程”与它无关。Defer 语句在周围函数返回时运行。在您的情况下,周围的函数是您的匿名func()传递给(并被调用)It。

BIG阳

您是否计划并行运行测试?如果是这样,那么结果将是不可预测的。在这种情况下,建议为每个进程设置一个单独的外部资源实例。我建议看看控制器测试是如何在 controller-runtime 中实现的。我相信,每次调用函数时,他们都会使用envtest创建新的控制平面。正如银杏文档所述:BeforeSuit并行运行时,每个并行进程都会运行BeforeSuite和AfterSuite函数
随时随地看视频慕课网APP

相关分类

Go
我要回答