0

我有一个大致如下的代码库

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。我在调试模式下检查了代码,并意识到问题出impl.GoRoutineWaitgroup.Add(1)在方法上validateMyFunction,当我注释掉go validateMyFunction(a,b)并再次运行测试时,日志中没有出现恐慌。那么我该如何解决这个问题呢?如何处理从内部启动 goroutine 的函数的单元测试(如本例所示)?

4

1 回答 1

0

您需要将值初始化为GoRoutineWaitgroup字段。

ms := &Service{GoRoutineWaitgroup: &sync.WaitGroup{}}

或从定义中删除指针

type Service struct {
    Repo                 repo 
    GoRoutineWaitgroup   sync.WaitGroup
}

此外,我没有在您的代码中看到等待等待组。类似的东西ms.GoRoutineWaitgroup.Wait(),您需要将 impl.GoRoutineWaitgroup.Add(1) 移至MyFunctionfromvalidateMyFunction否则validateMyFunction将不会调用其中的代码

于 2021-11-17T20:19:56.430 回答