Skip to content
Santekno.com | Level Up Your Engineering Skills
ID
📖 0%
Go

16 Soft Delete dalam GORM: Panduan Lengkap dengan Unit Test

· 3 mnt baca ·Ihsan Arif

Pelajari cara menggunakan soft delete di GORM untuk menghapus data tanpa benar-benar menghapusnya. Panduan ini mencakup contoh kode, penjelasan, dan unit test menggunakan SQLMock.

Soft delete adalah fitur yang memungkinkan penghapusan data tanpa benar-benar menghapusnya dari database. GORM menyediakan mekanisme ini dengan menambahkan kolom DeletedAt secara otomatis dalam model.

1. Soft Delete

Contoh Kode

go
 1package main
 2
 3import (
 4    "database/sql"
 5    "fmt"
 6    "testing"
 7    "github.com/DATA-DOG/go-sqlmock"
 8    "gorm.io/driver/postgres"
 9    "gorm.io/gorm"
10    "gorm.io/gorm/clause"
11)
12
13type User struct {
14    ID        uint `gorm:"primaryKey"`
15    Name      string
16    DeletedAt gorm.DeletedAt `gorm:"index"`
17}
18
19func softDeleteUser(db *gorm.DB, userID uint) error {
20    result := db.Delete(&User{}, userID)
21    return result.Error
22}

Penjelasan Kode

  • Mendefinisikan model User dengan kolom DeletedAt, yang memungkinkan fitur soft delete.
  • Fungsi softDeleteUser akan menghapus user berdasarkan ID dengan metode Delete(), yang hanya menandai DeletedAt tanpa benar-benar menghapus data dari database.

Unit Test

go
 1func TestSoftDeleteUser(t *testing.T) {
 2    db, mock, _ := sqlmock.New()
 3    defer db.Close()
 4    gormDB, _ := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})
 5
 6    mock.ExpectExec("UPDATE users").WillReturnResult(sqlmock.NewResult(1, 1))
 7
 8    err := softDeleteUser(gormDB, 1)
 9    if err != nil {
10        t.Errorf("Error soft deleting user: %v", err)
11    }
12}

Penjelasan Kode Unit Test

  • Menggunakan SQLMock untuk meniru query yang dijalankan saat melakukan soft delete.
  • Melakukan mocking untuk query UPDATE users yang mengubah nilai DeletedAt.
  • Memastikan fungsi softDeleteUser berjalan tanpa error.

2. Menemukan Data yang Sudah Dihapus

Contoh Kode

go
1func findDeletedUsers(db *gorm.DB) ([]User, error) {
2    var users []User
3    result := db.Unscoped().Where("deleted_at IS NOT NULL").Find(&users)
4    return users, result.Error
5}

Penjelasan Kode

  • Fungsi findDeletedUsers akan mencari data user yang telah dihapus.
  • Menggunakan Unscoped() agar query dapat mengakses data dengan deleted_at IS NOT NULL.

Unit Test

go
 1func TestFindDeletedUsers(t *testing.T) {
 2    db, mock, _ := sqlmock.New()
 3    defer db.Close()
 4    gormDB, _ := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})
 5
 6    rows := sqlmock.NewRows([]string{"id", "name", "deleted_at"}).
 7        AddRow(1, "Charlie", "2024-01-01")
 8    mock.ExpectQuery("SELECT * FROM users").WillReturnRows(rows)
 9
10    users, err := findDeletedUsers(gormDB)
11    if err != nil || len(users) == 0 {
12        t.Errorf("Failed to retrieve deleted users")
13    }
14}

Penjelasan Kode Unit Test

  • Membuat mock hasil query untuk mencari user yang memiliki deleted_at tidak null.
  • Menambahkan data mock berisi satu user yang dihapus.
  • Menguji apakah fungsi findDeletedUsers dapat mengambil data tersebut tanpa error.

3. Menghapus Permanen Data

Contoh Kode

go
1func permanentlyDeleteUser(db *gorm.DB, userID uint) error {
2    result := db.Unscoped().Delete(&User{}, userID)
3    return result.Error
4}

Penjelasan Kode

  • Fungsi permanentlyDeleteUser menggunakan Unscoped().Delete() untuk benar-benar menghapus data dari database.
  • Berbeda dengan soft delete, data yang dihapus dengan metode ini tidak bisa dikembalikan.

Unit Test

go
 1func TestPermanentlyDeleteUser(t *testing.T) {
 2    db, mock, _ := sqlmock.New()
 3    defer db.Close()
 4    gormDB, _ := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})
 5
 6    mock.ExpectExec("DELETE FROM users").WillReturnResult(sqlmock.NewResult(1, 1))
 7
 8    err := permanentlyDeleteUser(gormDB, 1)
 9    if err != nil {
10        t.Errorf("Error permanently deleting user: %v", err)
11    }
12}

Penjelasan Kode Unit Test

  • Menggunakan SQLMock untuk mengekspektasikan query DELETE FROM users.
  • Memastikan fungsi permanentlyDeleteUser dijalankan tanpa error.

Kesimpulan

  • Soft delete hanya menandai data sebagai dihapus tanpa benar-benar menghapusnya.
  • Data yang sudah dihapus bisa ditemukan dengan Unscoped().Where("deleted_at IS NOT NULL").
  • Penghapusan permanen bisa dilakukan dengan Unscoped().Delete(), yang akan benar-benar menghapus data dari database.
IH
Ihsan Arif
Backend engineer & penulis di Santekno. Aktif menulis tentang Go, Laravel, dan arsitektur backend modern.
Follow

💬 Komentar