I'm learning go and am working on a simple service that ingests some data from a queue and sticks it in the database. It also runs a web server to allow scraping of data. Right now I have two go files (omitted some text for brevity):
func main() {
parseConfig()
s := &Service{ServiceConfig: config}
err := s.Run()
if err != nil {
panic(err)
}
}
And then the definition of the service (again left out some pieces for brevity):
func (s *Service) Run() error {
if err := s.validate(); err != nil {
return err
}
if err := s.initDB(); err != nil {
return err
}
defer s.db.Close()
// Same pattern with health check library (init, start, close)
// Same pattern starting queue consumer (init, start, close)
s.mux = http.NewServeMux()
s.registerHandlers(s.mux)
http.ListenAndServe(":8080", s.mux)
return nil
}
And the struct
type Service struct {
Config // Hold db connection info
db *sql.DB
hc *health
}
I'm able to test the individual pieces fine (like initDB
or validate
) but I'm not unclear how one would test the Run
function because http.ListenAndServe blocks. I eventually time out. Previously, I would use httpTest and make a test server but that was when main
would start the server (the application was more basic at first).
Some things I would test:
That I can hit the metrics endpoint once started.
That I can hit the health endpoint once started.
That I can push a message on the queue and it is received once started.
That Run
actually starts w/o a panic.
Some notes: I am using docker to spin up a queue and database. The point of testing the Run
function is to ensure that the bootstrapping works and the application can run successfully. Eventually I will want to push data through the queue and assert that its been processed correctly.
Question: How should I test this or refactor it so that it is more easily testable end to end?