1 回答
TA贡献1804条经验 获得超3个赞
尽管在第一个测试的父上下文上调用了 cancel()。
在写入done和调用之间有一些时间cancel(),这意味着第一个测试可能(并且确实)进入第二for/select次迭代而不是退出 on <-ctx.Done()。更具体地说,测试代码在取消之前包含 2 个断言:
assert.Exactly(t, 1, len(executor.ExecuteCalls()))
assert.Exactly(t, "foobar", executor.ExecuteCalls()[0].In1)
然后才defer cancel()开始,这似乎为时已晚,无法取消第一个 go 例程的上下文。
如果您cancel()在读取之前移动 call done,则测试通过:
func TestProcessQueue(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
executor := &CommandExecutorMock{
ExecuteFunc: func(string) error {
return nil
},
}
done := make(chan struct{})
go processQueue(ctx, done, executor)
rc := pool.Get()
defer rc.Close()
_, err := rc.Do("RPUSH", commandsQueue, "foobar")
require.NoError(t, err)
cancel() // note this change right here
<-done
assert.Exactly(t, 1, len(executor.ExecuteCalls()))
assert.Exactly(t, "foobar", executor.ExecuteCalls()[0].In1)
}
- 1 回答
- 0 关注
- 100 浏览
添加回答
举报