Skip to content

Golang mock test db

Interfaces example for db operations mocking a db with a map where data is stored.

package main

import (
    "fmt"
    "log"
)

// Creating the User Struct to hold the user's ID and Name
type User struct {
    ID    int
    First string
}

// MockDataStore is a temporary service that stores retrievable data simulating database
// Its as truct that holds the Users map with int key for ID and User struct for values.
type MockDataStore struct {
    Users map[int]User
}

func (md MockDataStore) GetUser(id int) (User, error) {
    user, ok := md.Users[id]
    if !ok {
        return User{}, fmt.Errorf("User %s not found", id)
    }
    return user, nil
}

func (md MockDataStore) SaveUser(u User) error {
    _, ok := md.Users[u.ID]
    if ok {
        return fmt.Errorf("User %v already exists", u.ID)
    }
    md.Users[u.ID] = u
    return nil
}

type Datastore interface {
    GetUser(id int) (User, error)
    SaveUser(u User) error
}

type Service struct {
    ds Datastore
}

func (s Service) GetUser(id int) (User, error) {
    return s.ds.GetUser(id)
}

func (s Service) SaveUser(u User) error {
    return s.ds.SaveUser(u)
}
func main() {

    db := MockDataStore{
        Users: make(map[int]User),
    }
    srvc := Service{
        ds: db,
    }
    u1 := User{
        ID:    1,
        First: "Vladimir",
    }

    err := srvc.SaveUser(u1)
    if err != nil {
        log.Fatalf("Error %s", err)
    }
    u1Returned, err := srvc.GetUser(u1.ID)
    if err != nil {
        log.Fatalf("Error", err)

    }
    u2 := User{
        ID:    5,
        First: "Vladmin",
    }

    err2 := srvc.SaveUser(u2)
    if err2 != nil {
        log.Fatalf("Error ", err2)
    }
    u2Returned, err3 := srvc.GetUser(u2.ID)
    if err != nil {
        log.Fatalf("Error", err3)
    }

    fmt.Println(u1)
    fmt.Println(u1Returned)
    fmt.Println("User 2", u2)
    fmt.Println("User 2 returned", u2Returned)

    for key, val := range db.Users {
        fmt.Printf("User ID: %d\tUserName: %v\n", key, val.First)
    }
}