英文:
Run http.ListenAndServe() On Tests using stretchr/testify suite Stop Test From Proceed
问题
我正在尝试为我使用gorilla/mux、gorm.io和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)
// 大量的router.HandleFunc()
http.ListenAndServe(":8080", router)
}
问题是:如果我从SetupSuite()
中移除router.HandleRequests()
,所有的数据库测试都能正常运行,但是如果我尝试使用http.ListenAndServe()
,测试工作流会停止,什么都不会发生。
我相信我应该使用goroutines和router.HandleRequests()
,这样它就可以与测试并行运行,我只是不知道如何做到这一点。
更多信息,请参阅项目repository,我不知道这是否相关,但我正在使用docker-compose
运行两个postgres实例,一个用于项目运行,另一个用于测试。
英文:
I'm trying to create integration tests for my REST API application which I made using gorilla/mux, gorm.io and golang-migrate/v4
For the tests I'm using testify.
My SetupSuite()
in my integration_Test.go
is like this:
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()
}
And my router.HandleRequests()
is like this:
func HandleRequests() {
router := mux.NewRouter()
router.Use(middleware)
// lots of router.HandleFunc()
http.ListenAndServe(":8080", router)
}
The thing is: if I remove router.HandleRequests()
from the SetupSuite()
, all my database tests run normally, but if I try to http.ListenAndServe()
the test workflow stop and nothing happens.
I believe that I should use goroutines with router.HandleRequests()
so it can run parallel with the tests, I just can't figure it out how to do it.
For further information, here is the project repository, and I don't know if it is relevant, but I'm running two postgres instances using docker-compose
, one for the project to run and another for the tests.
答案1
得分: 1
我找到了使用Go协程来实现的方法。
我阅读了这个示例,它教你如何使用通道处理os.Signals
,我按照以下方式实现了它:
首先,在路由器中进行了以下更改:
func HandleRequests() {
router := mux.NewRouter()
router.Use(middleware)
// 大量的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
处停止,等待一个信号继续执行。
然后,我修复了SetupSuite()
,在一个goroutine中运行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() {
// 一些数据库代码
p, _ := os.FindProcess(os.Getpid())
p.Signal(syscall.SIGINT)
}
英文:
I figured out how to do it using go routines.
I read this example which teaches how to deal with os.Signals
using channels and I implemented it this way:
First, I made the following changes at the router:
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
}
So now http.ListenAndServe()
is running in a new thread. I believe that by a default behavior, it stops at the end of the program execution.
After http.ListenAndServe()
, I created a os.Signal
chanel which will listen to incomming signals from the system (SIGINT and SIGTERM), then the function will stop at <-quit
, which will be wating for one signal to continue.
Then I fixed my SetupSuite()
to run router.HandleRequests()
in a goroutine:
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()
}
And at my TearDownSuite()
I send a SIGTERM signal to the current process, wich will be listened by the quit
channel I've created before at router.HandleRequests()
and the function will proceed to terminate the program.
func (s *ReceiptServiceTestSuite) TearDownSuite() {
// some database code
p, _ := os.FindProcess(os.Getpid())
p.Signal(syscall.SIGINT)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论