I have written a large number of tests for my API in one file, and everything works fine there. Now I want to separate these tests into individual files, and no matter what I’ve tried, as you can see in the [repository] (GitHub - ku9nov/SAU: Simple Auto Updater service written in Golang.), I’m using the handler module, so I can’t place the tests in the handler module as there is a cyclic dependency. Also, for the tests to pass, there must be a connection to the database, so connecting to it is mandatory for all functions.
With moving the tests to a separate folder, I haven’t had any success either.
Let’s consider the simplest example: this is my server_test.go
file.
package main
var (
client *mongo.Client
appDB db.AppRepository
mongoDatabase *mongo.Database
configDB connstring.ConnString
s3Endpoint string
)
func TestMain(m *testing.M) {
// Set up resources before running tests
setup()
// Run the tests
code := m.Run()
teardown()
os.Exit(code)
}
func copyFile(src, dst string) {
input, err := os.ReadFile(src)
if err != nil {
logrus.Errorf("Failed to read the file: %v", err)
return
}
err = os.WriteFile(dst, input, 0644)
if err != nil {
logrus.Errorf("Failed to copy the file: %v", err)
return
}
}
func removeFile(filename string) {
err := os.Remove(filename)
if err != nil {
logrus.Errorf("Failed to remove the file: %v", err)
return
}
}
func setup() {
viper.SetConfigType("env")
viper.SetConfigName(".env")
// set the configuration file path
viper.AddConfigPath(".")
// read in the configuration file
if err := viper.ReadInConfig(); err != nil {
panic(err)
}
// Create a single database connection
flagMap := map[string]interface{}{
"migration": true,
"rollback": false,
"user_name": "admin",
"user_password": "password",
}
s3Endpoint = viper.GetString("S3_ENDPOINT")
client, configDB = mongod.ConnectToDatabase(viper.GetString("MONGODB_URL_TESTS"), flagMap)
appDB = mongod.NewAppRepository(&configDB, client)
mongoDatabase = client.Database(configDB.Database)
copyFile("LICENSE", "testapp.dmg")
copyFile("LICENSE", "testapp.pkg")
}
func teardown() {
adminsCollection := mongoDatabase.Collection("admins")
filter := bson.M{"username": "admin"}
// Delete the admin user from the collection
_, err := adminsCollection.DeleteOne(context.TODO(), filter)
if err != nil {
logrus.Errorf("Failed to remove admin user: %v", err)
}
log.Println("Successfully removed admin user.")
client.Disconnect(context.Background())
log.Println("MongoDB is disconnected.")
removeFile("testapp.dmg")
removeFile("testapp.pkg")
}
func TestHealthCheck(t *testing.T) {
router := gin.Default()
w := httptest.NewRecorder()
handler := handler.NewAppHandler(client, appDB, mongoDatabase)
router.GET("/health", func(c *gin.Context) {
handler.HealthCheck(c)
})
req, _ := http.NewRequest("GET", "/health", nil)
// Serve the request using the Gin router.
router.ServeHTTP(w, req)
// Check the response status code.
assert.Equal(t, http.StatusOK, w.Code)
// Check the response body.
expected := `{"status":"healthy"}`
assert.Equal(t, expected, w.Body.String())
}
How can I correctly move the TestHealthCheck
function to tests/info_test.go
? Of course, passing the database connection parameters to it…