Go goroutine测试未通过预期的调用数

Go goroutine测试未通过预期的调用数,go,testify,Go,Testify,我是新来的。我试图在Go例程中测试函数调用,但失败并显示错误消息 预期呼叫数(8)与实际呼叫数不匹配 (0) 我的测试代码如下: package executor import ( "testing" "sync" "github.com/stretchr/testify/mock" ) type MockExecutor struct { mock.Mock wg sync.WaitGroup }

我是新来的。我试图在Go例程中测试函数调用,但失败并显示错误消息

预期呼叫数(8)与实际呼叫数不匹配 (0)

我的测试代码如下:

package executor

import (
    "testing"
  "sync"
    "github.com/stretchr/testify/mock"
)

type MockExecutor struct {
    mock.Mock
  wg sync.WaitGroup
}

func (m *MockExecutor) Execute() {
  defer m.wg.Done()
}

func TestScheduleWorksAsExpected(t *testing.T) {

    scheduler := GetScheduler()
    executor := &MockExecutor{}
    scheduler.AddExecutor(executor)

    // Mock exptectations
    executor.On("Execute").Return()
    

    // Function Call
  executor.wg.Add(8)
    scheduler.Schedule(2, 1, 4)
  executor.wg.Wait()

  executor.AssertNumberOfCalls(t, "Execute", 8)

}
我的申请代码是:

package executor

import (
    "sync"
    "time"
)

type Scheduler interface {
    Schedule(repeatRuns uint16, coolDown uint8, parallelRuns uint64)
    AddExecutor(executor Executor)
}

type RepeatScheduler struct {
    executor  Executor
    waitGroup sync.WaitGroup
}

func GetScheduler() Scheduler {
    return &RepeatScheduler{}
}

func (r *RepeatScheduler) singleRun() {
    defer r.waitGroup.Done()
    r.executor.Execute()
}

func (r *RepeatScheduler) AddExecutor(executor Executor) {
    r.executor = executor
}

func (r *RepeatScheduler) repeatRuns(parallelRuns uint64) {
    for count := 0; count < int(parallelRuns); count += 1 {
        r.waitGroup.Add(1)
        go r.singleRun()
    }

    r.waitGroup.Wait()
}

func (r *RepeatScheduler) Schedule(repeatRuns uint16, coolDown uint8, parallelRuns uint64) {

    for repeats := 0; repeats < int(repeatRuns); repeats += 1 {
        r.repeatRuns(parallelRuns)
        time.Sleep(time.Duration(coolDown))
    }

}
包执行器
进口(
“同步”
“时间”
)
类型调度器接口{
计划(重复运行uint16、冷却运行uint8、并行运行uint64)
加法器(执行器执行器)
}
类型RepeatScheduler结构{
遗嘱执行人
waitGroup sync.waitGroup
}
func GetScheduler()调度程序{
返回和重复调度程序{}
}
func(r*RepeatScheduler)singleRun(){
延迟r.waitGroup.Done()
r、 executor.Execute()
}
func(r*RepeatScheduler)加法器(执行器){
r、 执行人
}
func(r*RepeatScheduler)repeatRuns(parallelRuns uint64){
对于计数:=0;计数
你能告诉我我在这里做错了什么吗?我用的是围棋1.16.3。调试代码时,我可以看到正在调用Execute()函数,但无法注册需要调用的函数调用,因此
mock.mock
记录已调用
Execute()
的事实。由于您不担心参数或返回值,以下内容应该可以解决您的问题:

func(m*MockExecutor)Execute(){
推迟m.wg.完成()
m、 称为()
}
但是我注意到,您当前编写测试的方式—此测试可能无法完成您想要的。这是因为:

  • 在调用
    executor.AssertNumberOfCalls
    之前,您正在调用
    executor.wg.Wait()
    (将等待函数被调用的预期次数),因此如果
    Execute()
    未被调用至少预期次数(
    wg.Wait()
    将永远阻塞),您的测试将永远无法完成
  • 调用
    m.Called()
    后,出现争用条件的预期次数(如果
    executor
    仍在运行,则
    executor.AssertNumberOfCalls
    与下一个
    m.Called()
    之间存在争用)。如果<代码> WG.DONE()<代码>确实被调用额外的时间,您将得到恐慌(我猜您可以考虑失败),但我可能会简化测试一点:
scheduler.Schedule(2,1,4)
time.Sleep(time.millis秒)//等待足够长的时间,以确保所有执行都已完成(当计划等待go例程结束时,应该很快)
执行人.资产编号调用(t,“执行”,8)

谢谢您的回复。我看到
m.Called()
如何帮助我的用例。另外,在理想情况下,如果我能在等待()时有一个超时时间,这会有所帮助,但我会选择这个。谢谢