运行 http.ListenAndServe() On Tests using stretchr/testify suite 从继续停止测试

Run http.ListenAndServe() On Tests using stretchr/testify suite Stop Test From Proceed

我正在尝试为我使用 gorilla/mux, gorm.io and golang-migrate/v4

创建的 REST API 应用程序创建集成测试

对于我正在使用的测试 testify

我的integration_Test.go里面的SetupSuite()是这样的:

func (s *ReceiptServiceTestSuite) SetupSuite() {
    s.Require().NoError(godotenv.Load("test.env"))
    s.Require().NoError(database.Connect())
    s.db = database.DB
    s.m = database.M

    router.HandleRequests()
}

而我的router.HandleRequests()是这样的:

func HandleRequests() {
    router := mux.NewRouter()
    router.Use(middleware)
    // lots of router.HandleFunc()
    
    http.ListenAndServe(":8080", router)
}

问题是:如果我从 SetupSuite() 中删除 router.HandleRequests(),我所有的数据库都会正常测试 运行,但是如果我尝试 http.ListenAndServe(),测试工作流程就会停止什么也没发生。

我相信我应该将 goroutines 与 router.HandleRequests() 一起使用,这样它就可以 运行 与测试并行,我只是不知道该怎么做。

有关更多信息,这里是项目 repository,我不知道它是否相关,但我正在 运行 使用 docker-compose 创建两个 postgres 实例,一个用于 运行 项目,另一个用于测试。

我知道如何使用 go routines 来做到这一点。

我读了这个 example,它教如何使用通道处理 os.Signals,我是这样实现的:

首先,我在路由器上做了以下改动:

func HandleRequests() {
    router := mux.NewRouter()
    router.Use(middleware)
    // lots of router.HandleFunc()
    
    go http.ListenAndServe(":8080", router)

    quit := make(chan os.Signal, 1)
    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

    <-quit

}

所以现在 http.ListenAndServe() 运行正在新线程中。我相信默认情况下,它会在程序执行结束时停止。

http.ListenAndServe() 之后,我创建了一个 os.Signal 通道,它将监听来自系统的传入信号(SIGINT 和 SIGTERM),然后该函数将停止在 <-quit,这将等待一个信号继续。

然后我在 goroutine 中将 SetupSuite() 固定为 运行 router.HandleRequests()

func (s *ReceiptServiceTestSuite) SetupSuite() {
    s.Require().NoError(godotenv.Load("test.env"))
    s.Require().NoError(database.Connect())
    s.db = database.DB
    s.m = database.M

    go router.HandleRequests()
}

并且在我的 TearDownSuite() 中,我向当前进程发送了一个 SIGTERM 信号,我之前在 router.HandleRequests() 中创建的 quit 通道将监听该信号,该函数将继续终止程序。

func (s *ReceiptServiceTestSuite) TearDownSuite() {
    // some database code 
    p, _ := os.FindProcess(os.Getpid())
    p.Signal(syscall.SIGINT)
}