Description

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, 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.

How to reproduce

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...

Expectations

I'm expecting find way to separate tests between multiple files.

Actual result

Without result.

Environment

  • go version: go version go1.21.1 darwin/arm64
  • gin version (or commit ref): 1.9.1
  • operating system: MacOS Sonoma