You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go单元测试中校验sync.WaitGroup.Done()是否被正常调用

测试方案

推荐方案:带超时的非阻塞等待测试(无代码侵入)

这个方案不需要修改原有业务代码,也不需要做接口适配,更不会出现panic问题,实现逻辑非常简单:给WaitGroup的等待操作加超时阈值,wg.Done()如果正常调用,等待会立刻结束,超过阈值则判定测试失败。

测试代码示例:

import (
    "sync"
    "testing"
    "time"
)

func TestF_WgDoneIsCalled(t *testing.T) {
    var wg sync.WaitGroup
    wg.Add(1)

    // 若f内部无其他异步逻辑,可直接同步调用f(&wg),不需要开goroutine
    go f(&wg)

    // 接收等待完成信号
    waitDone := make(chan struct{}, 1)
    go func() {
        wg.Wait()
        waitDone <- struct{}{}
    }()

    // 超时阈值可根据f的实际执行时长调整,单元测试一般设1秒完全足够
    select {
    case <-waitDone:
        // 正常返回,说明wg.Done()被正常调用
    case <-time.After(1 * time.Second):
        t.Fatal("f函数未正常执行wg.Done()")
    }
}

方案优势

  • 完全不侵入生产代码,不需要修改原函数的参数定义和实现逻辑
  • 不会出现panic问题,超时后只会标记测试失败,不会影响其他测试用例执行
  • 逻辑简单易懂,不需要额外的依赖和适配代码

如果你的测试场景完全不能接受超时判定,也可以选择对WaitGroup做极简的测试封装,仅在测试代码中继承sync.WaitGroup新增计数器统计Done的调用次数,不需要修改生产代码的参数类型,仅在测试时用子类实例传入即可,实现难度远低于完整的接口适配。

内容的提问来源于stack exchange,提问作者RasmusN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 21:06:04