[英]Unit testing of a function that starts a go routine inside it
我有一個大致如下的代碼庫
type Service struct {
Repo repo // An interface that contains both FunctionOne and FunctionTwo
GoRoutineWaitgroup *sync.WaitGroup
}
func (impl *Service) MyFunction(s string) bool {
a := impl.Repo.FunctionOne()
b := impl.Repo.FunctionTwo()
fmt.Println("Executed Function One and Function two")
go impl.validateMyFunction(a,b)
return true
}
func (impl *Service) validateMyFunction(a string,b string) {
defer helpers.PanicHandler()
impl.GoRoutineWaitgroup.Add(1)
defer impl.GoRoutineWaitgroup.Done()
fmt.Println("a and b are validated")
}
我編寫了與此類似的單元測試。
func TestMyFunction(t *testing.T) {
ms := &Service{}
test := []struct{
input string
output bool
case string
}{
{"a", true, sample}
}
}
for _, test := range tests {
t.Run(test.case, func(t *testing.T) {
mockRepo := new(mockrepo.Repo) // mockRepo contains mocks of original repo layer methods generated using mockery for testing purposes
mockRepo.On("FunctionOne")
mockRepo.On("FunctionTwo")
ms.Repo = mockRepo
op := ms.MyFunction(test.input)
assert.Equal(t, test.Output, op)
})
}
} // Please keep in mind that this is not my actual code, but just a basic structure.
所有測試均成功。 但是在執行命令go test -v
時,我在代碼中的多個地方看到程序出現恐慌並給出了invalid memory address or nil pointer dereference
。 我在調試模式下檢查了代碼,發現問題出在方法validateMyFunction
中的impl.GoRoutineWaitgroup.Add(1)
上,當我注釋掉go validateMyFunction(a,b)
並再次運行測試時,日志中沒有出現恐慌。 那么我該如何解決這個問題呢? 如何處理從內部啟動 goroutine 的函數的單元測試(如本例所示)?
您需要初始化GoRoutineWaitgroup
字段的值。
ms := &Service{GoRoutineWaitgroup: &sync.WaitGroup{}}
或從定義中刪除指針
type Service struct {
Repo repo
GoRoutineWaitgroup sync.WaitGroup
}
此外,我沒有在您的代碼中看到等待等待組。 像ms.GoRoutineWaitgroup.Wait()
類的東西,您需要將 impl.GoRoutineWaitgroup.Add(1) 從validateMyFunction
移動到MyFunction
否則validateMyFunction
中的代碼將不會被調用
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.