UJIAN INTEGRASI GOLANG DENGAN GIN, GORM, TESTIFY, MYSQL

Patricia Arquette
Lepaskan: 2024-10-18 14:07:02
asal
489 orang telah melayarinya

GOLANG INTEGRATION TEST WITH GIN, GORM, TESTIFY, MYSQL

Creating a comprehensive integration test for a Golang application using libraries like Gin, Gorm, Testify, and MySQL (using an in-memory solution) involves setting up a testing environment, defining routes and handlers, and testing them against an actual database (though using MySQL in-memory might require a workaround like using SQLite in in-memory mode for simplicity).

Here’s an example of an integration test setup:

1. Dependencies:

  • Gin: for creating the HTTP server.
  • Gorm: for ORM to interact with the database.
  • Testify: for assertions.
  • SQLite in-memory: acts as a substitute for MySQL during testing.

2. Setup:

  • Define a basic model and Gorm setup.
  • Create HTTP routes and handlers.
  • Write tests using Testify and SQLite as an in-memory database.

Here’s the full example:

// main.go
package main

import (
    "github.com/gin-gonic/gin"
    "gorm.io/driver/mysql"
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
    "net/http"
)

// User represents a simple user model.
type User struct {
    ID    uint   `gorm:"primaryKey"`
    Name  string `json:"name"`
    Email string `json:"email" gorm:"unique"`
}

// SetupRouter initializes the Gin engine with routes.
func SetupRouter(db *gorm.DB) *gin.Engine {
    r := gin.Default()

    // Inject the database into the handler
    r.POST("/users", func(c *gin.Context) {
        var user User
        if err := c.ShouldBindJSON(&user); err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            return
        }
        if err := db.Create(&user).Error; err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
            return
        }
        c.JSON(http.StatusCreated, user)
    })

    r.GET("/users/:id", func(c *gin.Context) {
        var user User
        id := c.Param("id")
        if err := db.First(&user, id).Error; err != nil {
            c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
            return
        }
        c.JSON(http.StatusOK, user)
    })

    return r
}

func main() {
    // For production, use MySQL
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }

    db.AutoMigrate(&User{})

    r := SetupRouter(db)
    r.Run(":8080")
}
Salin selepas log masuk

Integration Test

// main_test.go
package main

import (
    "bytes"
    "encoding/json"
    "github.com/stretchr/testify/assert"
    "net/http"
    "net/http/httptest"
    "testing"

    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

// SetupTestDB sets up an in-memory SQLite database for testing.
func SetupTestDB() *gorm.DB {
    db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
    if err != nil {
        panic("failed to connect to the test database")
    }
    db.AutoMigrate(&User{})
    return db
}

func TestCreateUser(t *testing.T) {
    db := SetupTestDB()
    r := SetupRouter(db)

    // Create a new user.
    user := User{Name: "John Doe", Email: "john@example.com"}
    jsonValue, _ := json.Marshal(user)
    req, _ := http.NewRequest("POST", "/users", bytes.NewBuffer(jsonValue))
    req.Header.Set("Content-Type", "application/json")
    w := httptest.NewRecorder()
    r.ServeHTTP(w, req)

    assert.Equal(t, http.StatusCreated, w.Code)

    var createdUser User
    json.Unmarshal(w.Body.Bytes(), &createdUser)
    assert.Equal(t, "John Doe", createdUser.Name)
    assert.Equal(t, "john@example.com", createdUser.Email)
}

func TestGetUser(t *testing.T) {
    db := SetupTestDB()
    r := SetupRouter(db)

    // Insert a user into the in-memory database.
    user := User{Name: "Jane Doe", Email: "jane@example.com"}
    db.Create(&user)

    // Make a GET request.
    req, _ := http.NewRequest("GET", "/users/1", nil)
    w := httptest.NewRecorder()
    r.ServeHTTP(w, req)

    assert.Equal(t, http.StatusOK, w.Code)

    var fetchedUser User
    json.Unmarshal(w.Body.Bytes(), &fetchedUser)
    assert.Equal(t, "Jane Doe", fetchedUser.Name)
    assert.Equal(t, "jane@example.com", fetchedUser.Email)
}

func TestGetUserNotFound(t *testing.T) {
    db := SetupTestDB()
    r := SetupRouter(db)

    // Make a GET request for a non-existent user.
    req, _ := http.NewRequest("GET", "/users/999", nil)
    w := httptest.NewRecorder()
    r.ServeHTTP(w, req)

    assert.Equal(t, http.StatusNotFound, w.Code)
}

Salin selepas log masuk

Explanation

  1. main.go:

    • Defines a User struct and sets up basic CRUD operations using Gin.
    • Uses Gorm for database interactions and auto-migrates the User table.
    • SetupRouter configures HTTP endpoints.
  2. main_test.go:

    • SetupTestDB initializes an in-memory SQLite database for isolated testing.
    • TestCreateUser: Tests the creation of a user.
    • TestGetUser: Tests fetching an existing user.
    • TestGetUserNotFound: Tests fetching a non-existent user.
    • Uses httptest.NewRecorder and http.NewRequest for simulating HTTP requests and responses.
    • Uses Testify for assertions, like checking HTTP status codes and verifying JSON responses.

Running the Tests

To run the tests, use:

go test -v
Salin selepas log masuk

Considerations

  • SQLite for In-memory Testing: This example uses SQLite for in-memory testing as MySQL doesn't natively support an in-memory mode with Gorm. For tests that rely on MySQL-specific features, consider using a Docker-based setup with a MySQL container.
  • Database Migrations: Always ensure the database schema is up-to-date using AutoMigrate in tests.
  • Isolation: Each test function initializes a fresh in-memory database, ensuring tests don't interfere with each other.

Atas ialah kandungan terperinci UJIAN INTEGRASI GOLANG DENGAN GIN, GORM, TESTIFY, MYSQL. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!