Skip to content

Commit 1511294

Browse files
committed
Implement mock database for testing
1 parent 8ca0a75 commit 1511294

File tree

9 files changed

+134
-85
lines changed

9 files changed

+134
-85
lines changed

config/config.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
package config
22

33
import (
4+
"os"
5+
46
"github.com/spf13/viper"
57
)
68

79
type Config struct {
8-
InfuraProjectID string `mapstructure:"infura.project_id"`
9-
DatabaseURL string `mapstructure:"database.url"`
10-
SendGridAPIKey string `mapstructure:"sendgrid.api_key"`
10+
DatabaseURL string
11+
SendGridAPIKey string
12+
InfuraProjectID string
1113
}
1214

1315
func LoadConfig() (*Config, error) {
16+
if os.Getenv("GO_ENV") == "test" {
17+
return &Config{
18+
DatabaseURL: "test_db_url",
19+
SendGridAPIKey: "test_api_key",
20+
InfuraProjectID: "test_infura_id",
21+
}, nil
22+
}
1423
viper.SetConfigName("config")
1524
viper.AddConfigPath(".")
1625
viper.SetConfigType("yaml")

database/_database_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package database
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestInitDB(t *testing.T) {
10+
SetupMockDB()
11+
defer ResetMockDB()
12+
13+
t.Run("Mock Mode", func(t *testing.T) {
14+
db, err := InitDB("any-dsn")
15+
assert.Nil(t, err)
16+
assert.Nil(t, db)
17+
})
18+
19+
t.Run("Empty DSN", func(t *testing.T) {
20+
IsMockMode = false
21+
db, err := InitDB("")
22+
assert.Error(t, err)
23+
assert.Nil(t, db)
24+
})
25+
}

database/database.go

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,58 @@
11
package database
22

33
import (
4-
"gorm.io/driver/postgres"
4+
"errors"
5+
"io"
6+
"log"
7+
"os"
8+
"sync"
9+
510
"gorm.io/gorm"
611
)
712

8-
// Exported DB variable
9-
var DB *gorm.DB
13+
var (
14+
DB *gorm.DB
15+
IsMockMode bool
16+
ErrMockMode = errors.New("database is in mock mode")
17+
logger = log.New(os.Stdout, "", log.LstdFlags)
18+
mu sync.Mutex
19+
)
1020

11-
func InitDB(dsn string) error {
12-
var err error
13-
DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})
14-
if err != nil {
15-
return err
21+
func init() {
22+
// Setup mock DB in test mode
23+
if os.Getenv("GO_ENV") == "test" {
24+
SetupMockDB()
25+
logger.SetOutput(io.Discard) // Use SetOutput instead of creating new logger
1626
}
17-
return nil
27+
}
28+
29+
func InitDB(dsn string) (*gorm.DB, error) {
30+
IsMockMode = true
31+
mu.Lock()
32+
defer mu.Unlock()
33+
34+
// Skip DB initialization in mock mode
35+
if IsMockMode {
36+
return nil, nil
37+
}
38+
39+
return nil, nil
40+
}
41+
42+
func SetupMockDB() {
43+
mu.Lock()
44+
defer mu.Unlock()
45+
46+
IsMockMode = true
47+
DB = nil
48+
logger = log.New(io.Discard, "", 0)
49+
}
50+
51+
func ResetMockDB() {
52+
mu.Lock()
53+
defer mu.Unlock()
54+
55+
IsMockMode = false
56+
DB = nil
57+
logger = log.New(os.Stdout, "", log.LstdFlags)
1858
}

go.mod

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ require (
77
github.com/sendgrid/sendgrid-go v3.16.0+incompatible
88
github.com/spf13/viper v1.19.0
99
github.com/stretchr/testify v1.10.0
10-
gorm.io/driver/postgres v1.5.10
1110
gorm.io/gorm v1.25.12
1211
)
1312

@@ -29,10 +28,6 @@ require (
2928
github.com/gorilla/websocket v1.4.2 // indirect
3029
github.com/hashicorp/hcl v1.0.0 // indirect
3130
github.com/holiman/uint256 v1.3.1 // indirect
32-
github.com/jackc/pgpassfile v1.0.0 // indirect
33-
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
34-
github.com/jackc/pgx/v5 v5.5.5 // indirect
35-
github.com/jackc/puddle/v2 v2.2.1 // indirect
3631
github.com/jinzhu/inflection v1.0.0 // indirect
3732
github.com/jinzhu/now v1.1.5 // indirect
3833
github.com/magiconair/properties v1.8.7 // indirect

go.sum

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,6 @@ github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs
8686
github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
8787
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
8888
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
89-
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
90-
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
91-
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
92-
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
93-
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
94-
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
95-
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
96-
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
9789
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
9890
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
9991
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
@@ -177,7 +169,6 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
177169
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
178170
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
179171
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
180-
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
181172
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
182173
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
183174
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
@@ -234,8 +225,6 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
234225
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
235226
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
236227
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
237-
gorm.io/driver/postgres v1.5.10 h1:7Lggqempgy496c0WfHXsYWxk3Th+ZcW66/21QhVFdeE=
238-
gorm.io/driver/postgres v1.5.10/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
239228
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
240229
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
241230
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=

main.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// main.go
12
package main
23

34
import (
@@ -19,17 +20,23 @@ import (
1920
)
2021

2122
func init() {
23+
// Skip completely in test mode
2224
if os.Getenv("GO_ENV") == "test" {
25+
database.SetupMockDB() // Set mock mode
2326
return
2427
}
28+
29+
// Only run DB initialization in non-test mode
2530
cfg, err := config.LoadConfig()
2631
if err != nil {
2732
log.Fatal("Failed to load config:", err)
2833
}
2934

30-
err = database.InitDB(cfg.DatabaseURL)
31-
if err != nil {
32-
log.Fatal("Failed to initialize database:", err)
35+
if _, err := database.InitDB(cfg.DatabaseURL); err != nil {
36+
// Only log error in non-test mode
37+
if !database.IsMockMode {
38+
log.Fatal("Failed to initialize database:", err)
39+
}
3340
}
3441
}
3542

main_test.go

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,45 +10,39 @@ import (
1010
)
1111

1212
func TestMain(m *testing.M) {
13+
// Set test environment
1314
os.Setenv("GO_ENV", "test")
15+
// Run tests
1416
os.Exit(m.Run())
1517
}
1618

1719
func TestNotifyUsers(t *testing.T) {
18-
// Create a sample event to pass to notifyUsers
1920
event := &models.Event{
2021
TxHash: "0xabc123",
2122
FromAddress: "0xfrom",
2223
ToAddress: "0xto",
23-
Value: "1000000000000000000", // 1 ETH in Wei
24+
Value: "1000000000000000000",
2425
EventType: "LARGE_TRANSFER",
2526
}
2627

27-
// Initialize the mock repositories and services
28+
emailSent := false
2829
mockUserPrefRepo := &mock.MockUserPreferenceRepository{
2930
GetMatchingPreferencesFunc: func(event *models.Event) ([]models.UserPreference, error) {
30-
return []models.UserPreference{
31-
{
32-
UserID: "user@example.com",
33-
WalletAddress: event.ToAddress,
34-
EmailNotification: true,
35-
},
36-
}, nil
31+
return []models.UserPreference{{
32+
UserID: "user@example.com",
33+
WalletAddress: event.ToAddress,
34+
EmailNotification: true,
35+
}}, nil
3736
},
3837
}
3938

40-
emailSent := false
41-
4239
mockEmailNotification := &mock.MockEmailNotification{
4340
SendFunc: func(event *models.Event, userPref *models.UserPreference) error {
4441
emailSent = true
4542
return nil
4643
},
4744
}
4845

49-
// Call the function under test
5046
notifyUsers(event, mockUserPrefRepo, mockEmailNotification)
51-
52-
// Assert that email was sent
5347
assert.True(t, emailSent, "Email notification should have been sent")
5448
}

mock/database_mock.go

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,19 @@ package mock
22

33
import (
44
"github.com/Jetlum/WalletAlertService/models"
5-
"gorm.io/gorm"
65
)
76

87
type MockDB struct {
98
Events []models.Event
109
UserPreferences []models.UserPreference
1110
}
1211

13-
func NewMockDB() *MockDB {
14-
return &MockDB{
15-
Events: []models.Event{},
16-
UserPreferences: []models.UserPreference{},
17-
}
12+
var TestDB = &MockDB{
13+
Events: make([]models.Event, 0),
14+
UserPreferences: make([]models.UserPreference, 0),
1815
}
1916

20-
func (db *MockDB) Create(value interface{}) *gorm.DB {
21-
switch v := value.(type) {
22-
case *models.Event:
23-
db.Events = append(db.Events, *v)
24-
case *models.UserPreference:
25-
db.UserPreferences = append(db.UserPreferences, *v)
26-
}
27-
return &gorm.DB{}
28-
}
29-
30-
func (db *MockDB) Find(out interface{}, where ...interface{}) *gorm.DB {
31-
switch out := out.(type) {
32-
case *[]models.Event:
33-
*out = db.Events
34-
case *[]models.UserPreference:
35-
*out = db.UserPreferences
36-
}
37-
return &gorm.DB{}
17+
func ResetTestDB() {
18+
TestDB.Events = make([]models.Event, 0)
19+
TestDB.UserPreferences = make([]models.UserPreference, 0)
3820
}

mock/repository_mock.go

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,17 @@ package mock
22

33
import "github.com/Jetlum/WalletAlertService/models"
44

5-
type MockUserPreferenceRepository struct {
6-
GetMatchingPreferencesFunc func(event *models.Event) ([]models.UserPreference, error)
5+
// Mock Event Repository
6+
type MockEventRepository struct {
7+
CreateFunc func(event *models.Event) error
78
}
89

9-
func (m *MockUserPreferenceRepository) GetMatchingPreferences(event *models.Event) ([]models.UserPreference, error) {
10-
if m.GetMatchingPreferencesFunc != nil {
11-
return m.GetMatchingPreferencesFunc(event)
10+
func NewMockEventRepository() *MockEventRepository {
11+
return &MockEventRepository{
12+
CreateFunc: func(event *models.Event) error {
13+
return nil
14+
},
1215
}
13-
return nil, nil
14-
}
15-
16-
type MockEventRepository struct {
17-
CreateFunc func(event *models.Event) error
1816
}
1917

2018
func (m *MockEventRepository) Create(event *models.Event) error {
@@ -24,12 +22,22 @@ func (m *MockEventRepository) Create(event *models.Event) error {
2422
return nil
2523
}
2624

27-
// Constructor for MockUserPreferenceRepository
25+
// Mock User Preference Repository
26+
type MockUserPreferenceRepository struct {
27+
GetMatchingPreferencesFunc func(event *models.Event) ([]models.UserPreference, error)
28+
}
29+
2830
func NewMockUserPreferenceRepository() *MockUserPreferenceRepository {
29-
return &MockUserPreferenceRepository{}
31+
return &MockUserPreferenceRepository{
32+
GetMatchingPreferencesFunc: func(event *models.Event) ([]models.UserPreference, error) {
33+
return []models.UserPreference{}, nil
34+
},
35+
}
3036
}
3137

32-
// Constructor for MockEventRepository
33-
func NewMockEventRepository() *MockEventRepository {
34-
return &MockEventRepository{}
38+
func (m *MockUserPreferenceRepository) GetMatchingPreferences(event *models.Event) ([]models.UserPreference, error) {
39+
if m.GetMatchingPreferencesFunc != nil {
40+
return m.GetMatchingPreferencesFunc(event)
41+
}
42+
return []models.UserPreference{}, nil
3543
}

0 commit comments

Comments
 (0)