Skip to content
Wrapper for MongoDB and BoltDB with full mock coverage
Go
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
db second commit Aug 15, 2018
README.md link to thylog article added Aug 16, 2018

README.md

Wrapper with mocks for MongoDB and BoltDB

Package shows how to mock MongoDB or BoltDB using a single Go interface.
It's not cover all db methods from the globalsign/mgo driver's package.
Feel free to extend the package according to your needs.

Package inspired by this article - Mocking Mongo in Go

Table of contents

How to install

go get github.com/zaffka/mongodb-boltdb-mock

Package contents

  • Wrapper itself (db/db.go) with:

    • db.Handler - main interface for opening, closing and controling connection to DB
    • db.Querier - interface for selecting data from DB
    • db.Refiner - interface for refining query object obtained by the Find() method
  • Realization for the MongoDB (db/mgo.go)

  • Realization for the BoltDB (db/bolt.go)

  • A set of mocks (db/mock.go)

  • Unit tests (db/db_test.go)

Interface methods being in use by realization

Interface/Function MongoDB Mocks BoltDB
db.New() + + +
db.Handler      
Connect + + +
Copy + + -
CopyWithSettings + + -
Close + + +
ExecOn + + +
db.Querier      
Insert + + +
Remove + + +
RemoveAll + + -
Update + + -
UpdateAll + + -
Upsert + + -
Find + + +
db.Refiner      
One + + +
All + + -
Distinct + + -
Count + + -

MongoDB examples

...up the db

mongo := db.New(&db.Mongo{})
err := mongo.Connect("mongo://localhost:/27017")
defer mongo.Close()

...inserting data

func main() {
mongo := db.New(&db.Mongo{})
err := mongo.Connect("mongo://localhost:/27017")
defer mongo.Close()

os := new(OurStuct)
os.Save(mongo)
}

type OurStruct struct {}
func (o *OurStruct) Save(db db.Handler, databaseName, collectionName string) error {
    sess := db.Copy() //Pay attention globalsign's driver whant us to use
	defer sess.Close() //copied or clonned session of the *mgo.Session object

	err := sess.ExecOn(databaseName, collectionName).Insert(o)
	if err != nil {
		return err
	}

	return nil
}

...reading

func main() {
mongo := db.New(&db.Mongo{})
err := mongo.Connect("mongo://localhost:/27017")
defer mongo.Close()

os := new(OurStuct)
os.Save(mongo)
}

type OurStruct struct {
    ID bson.ObjectID `bson:"_id"`
}
func (o *OurStruct) Read(db db.Handler, databaseName, collectionName string) error {
	sess := db.Copy()
	defer sess.Close()

	err := sess.ExecOn(databaseName, collectionName).Find(o.ID).One(o)
	if err != nil {
		return err
	}

	return nil
}

...updating

func main() {
mongo := db.New(&db.Mongo{})
err := mongo.Connect("mongo://localhost:/27017")
defer mongo.Close()

os := new(OurStuct)
os.Save(mongo)
}

type OurStruct struct {
    ID bson.ObjectID `bson:"_id"`
}
func (o *OurStruct) Update(db db.Handler, databaseName, collectionName, update string) error {
	sess := db.Copy()
	defer sess.Close()

	_, err := sess.ExecOn(databaseName, collectionName).Upsert(bson.M{"_id": o.ID}, bson.M{"$set": bson.M{"somefield": update}})
	if err != nil {
		return err
	}

	return nil
}

and so on...

BoltDB examples

Features:

  • Database opens at the system's temp directory (/tmp @ linux)
  • Working directory with db file will look like /tmp/[basename][random numbers]/[basename]
  • bolt.Close() removes the working directory and a db file
  • Use boltbrowser to work with bolt's files
  • Any structs and data types can be used as keys and values to store in BoltDB (Gob marshaling\unmarshaling inside)
  • BoltDB uses buckets as Mongo's collections analogues

...up the db

bolt := db.New(&db.Bolt{})
err := bolt.Connect("bolt", "bucketOne", "bucketTwo")
defer bolt.Close()

Where "bolt" - it's a [basename] and others are variadic set of buckets names.
If the list scipped bucket with the default name being in use.

...inserting data

bolt := db.New(&db.Bolt{})
err := bolt.Connect("bolt", "bucketOne", "bucketTwo")
defer bolt.Close()

err = bolt.ExecOn("bucketOne").Insert("key", &db.Mock{Msg: "test"})
if err != nil {
	log.Error(err)
}

...reading

...
var res db.Mock
err := bolt.ExecOn("bucketOne").Find("key").One(&res)
...

...deleting

...
err := bolt.ExecOn("bucketOne").Remove("key")
...

Mocking

Just replace &db.Mongo{} (or &db.Bolt{}) with &db.Mock{} and cover your functions by unit tests with ease.
No real database needed.

func main() {
mongo := db.New(&db.Mongo{})
mongo.ExecOn(...).Find(...)...
...

replace with

func main() {
mock := db.New(&db.Mock{})
mongo.ExecOn(...).Find(...)...
...
You can’t perform that action at this time.