Maison  >  Article  >  développement back-end  >  Test d'intégration Golang avec Gin, Gorm, Testify, PostgreSQL

Test d'intégration Golang avec Gin, Gorm, Testify, PostgreSQL

DDD
DDDoriginal
2024-10-26 15:10:03468parcourir

Golang Integration Test With Gin, Gorm, Testify, PostgreSQL

La création d'une configuration de test d'intégration complète dans Golang avec Gin, GORM, Testify et PostgreSQL implique la configuration d'une base de données de tests, l'écriture de tests pour les opérations CRUD et l'utilisation de Testify pour les assertions. Voici un guide étape par étape pour vous aider à démarrer :

Conditions préalables

  • Allez installé
  • Docker installé
  • Bibliothèques : gin-gonic/gin, gorm.io/gorm, gorm.io/driver/postgres, testify, testcontainers-go

Structure du projet

myapp/
|-- main.go
|-- models/
|   |-- models.go
|-- handlers/
|   |-- handlers.go
|-- tests/
|   |-- integration_test.go
|-- go.mod
|-- go.sum

1. Configurer les modèles (models/models.go)

Définissez les modèles avec les balises GORM pour le mappage de base de données.

package models

import (
    "time"
    "gorm.io/gorm"
)

type User struct {
    ID        uint           `gorm:"primaryKey"`
    Name      string         `gorm:"not null"`
    Email     string         `gorm:"unique;not null"`
    CreatedAt time.Time
}

type Book struct {
    ID            uint           `gorm:"primaryKey"`
    Title         string         `gorm:"not null"`
    Author        string         `gorm:"not null"`
    PublishedDate time.Time      `gorm:"not null"`
}

type BorrowLog struct {
    ID         uint           `gorm:"primaryKey"`
    UserID     uint           `gorm:"not null"`
    BookID     uint           `gorm:"not null"`
    BorrowedAt time.Time      `gorm:"default:CURRENT_TIMESTAMP"`
    ReturnedAt *time.Time
}

2. Configurer les gestionnaires (handlers/handlers.go)

Définissez les routes et les gestionnaires pour les opérations CRUD à l'aide de Gin.

package handlers

import (
    "myapp/models"
    "net/http"

    "github.com/gin-gonic/gin"
    "gorm.io/gorm"
)

type Handler struct {
    DB *gorm.DB
}

func (h *Handler) CreateUser(c *gin.Context) {
    var user models.User
    if err := c.ShouldBindJSON(&user); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    if err := h.DB.Create(&user).Error; err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }

    c.JSON(http.StatusCreated, user)
}

func (h *Handler) GetUser(c *gin.Context) {
    var user models.User
    if err := h.DB.First(&user, c.Param("id")).Error; err != nil {
        c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
        return
    }

    c.JSON(http.StatusOK, user)
}

func (h *Handler) UpdateUser(c *gin.Context) {
    var user models.User
    if err := h.DB.First(&user, c.Param("id")).Error; err != nil {
        c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
        return
    }

    if err := c.ShouldBindJSON(&user); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    if err := h.DB.Save(&user).Error; err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }

    c.JSON(http.StatusOK, user)
}

func (h *Handler) DeleteUser(c *gin.Context) {
    if err := h.DB.Delete(&models.User{}, c.Param("id")).Error; err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }

    c.JSON(http.StatusOK, gin.H{"message": "User deleted"})
}

3. Application principale (main.go)

Configurez la connexion à la base de données et les itinéraires.

package main

import (
    "myapp/handlers"
    "myapp/models"
    "github.com/gin-gonic/gin"
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
    "log"
    "os"
)

func main() {
    dsn := "host=localhost user=postgres password=yourpassword dbname=testdb port=5432 sslmode=disable"
    db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
    if err != nil {
        log.Fatalf("failed to connect to database: %v", err)
    }

    // Auto migrate the models
    db.AutoMigrate(&models.User{}, &models.Book{}, &models.BorrowLog{})

    h := handlers.Handler{DB: db}

    r := gin.Default()

    r.POST("/users", h.CreateUser)
    r.GET("/users/:id", h.GetUser)
    r.PUT("/users/:id", h.UpdateUser)
    r.DELETE("/users/:id", h.DeleteUser)

    r.Run(":8080")
}

4. Test d'intégration (tests/integration_test.go)

Utilisez Testify pour configurer et valider les résultats des tests.

Pour la base de données, nous pouvons utiliser une instance PostgreSQL Dockerisée à des fins de test, qui est isolée et peut être rapidement démontée après les tests. Voici comment le configurer dans Golang à l'aide de testcontainers-go :

Installez testcontainers-go :

go get github.com/testcontainers/testcontainers-go

Voici le fichier Integration_test.go qui configure un conteneur PostgreSQL pour les tests :

myapp/
|-- main.go
|-- models/
|   |-- models.go
|-- handlers/
|   |-- handlers.go
|-- tests/
|   |-- integration_test.go
|-- go.mod
|-- go.sum

Explication

  • SetupTestDB : configure une connexion à la base de données PostgreSQL à l'aide de GORM pour les tests.
  • TestCreateUser : envoie une requête POST pour créer un nouvel utilisateur et affirme la réponse.
  • TestGetUser : Récupère un utilisateur par ID et vérifie que les données correspondent à ce qui a été inséré.
  • TestUpdateUser :
    • Crée un utilisateur et le met à jour à l'aide du point de terminaison PUT /users/:id.
    • Affirme que l'état de la réponse est 200 OK.
    • Vérifie que les détails de l'utilisateur sont mis à jour dans la réponse.
    • Récupère l'utilisateur de la base de données et confirme que les modifications sont conservées.
  • TestDeleteUser :
    • Crée un utilisateur et le supprime à l'aide du point de terminaison DELETE /users/:id.
    • Affirme que l'état de la réponse est 200 OK et recherche un message de réussite.
    • Tente de récupérer l'utilisateur supprimé de la base de données pour s'assurer que l'utilisateur n'existe plus, en affirmant une erreur gorm.ErrRecordNotFound.
  • testcontainers-go : Cette bibliothèque vous permet de lancer des conteneurs Docker directement à partir de votre code Go. C'est idéal pour créer une instance PostgreSQL temporaire pour les tests d'intégration.
  • setupTestDB : cette fonction démarre un conteneur PostgreSQL Docker, s'y connecte à l'aide de gorm et configure le schéma de base de données. Il garantit également que le conteneur est nettoyé une fois les tests terminés.
  • defer postgresC.Terminate(ctx) : garantit que le conteneur PostgreSQL est terminé une fois les tests effectués, simulant une approche en mémoire.
  • Hôte et port dynamiques : utilise l'hôte et le port alloués dynamiquement au conteneur pour se connecter à la base de données.

Exécution des tests

Exécutez les tests en utilisant :

myapp/
|-- main.go
|-- models/
|   |-- models.go
|-- handlers/
|   |-- handlers.go
|-- tests/
|   |-- integration_test.go
|-- go.mod
|-- go.sum
Avantages de l'utilisation de testcontainers-go :
  1. Isolement : chaque exécution de test obtient une nouvelle instance PostgreSQL, garantissant ainsi l'absence de fuite de données entre les tests.
  2. Réplique l'environnement de production : les tests sur une instance réelle de PostgreSQL fournissent des résultats plus fiables que l'utilisation d'une base de données en mémoire.
  3. Automation : démarre et arrête automatiquement le conteneur PostgreSQL, ce qui le rend facile à utiliser dans les pipelines CI/CD.

Points clés

  • Utiliser une base de données de test : C'est une bonne pratique d'utiliser une base de données PostgreSQL distincte (ex : celles conteneurisées) pour les tests afin d'éviter d'affecter les données de production.
  • Configuration et nettoyage : assurez-vous de nettoyer la base de données entre les tests pour maintenir la cohérence.
  • Testify : fournit des méthodes d'assertion puissantes pour valider les résultats.
  • Gin's Test Server : utilise httptest pour simuler les requêtes HTTP sur le serveur Gin.

Avec cette configuration, vous pouvez tester les opérations CRUD pour un modèle utilisateur, garantissant ainsi que l'API fonctionne comme prévu avec PostgreSQL. Vous pouvez étendre les tests de la même manière pour les modèles Book et BorrowLog.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn