Created
July 12, 2018 02:18
-
-
Save p4tin/061c3331e8235446188488780595d9a8 to your computer and use it in GitHub Desktop.
Mocking Mongo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package clients | |
import ( | |
"github.com/globalsign/mgo" | |
"testapp" | |
) | |
// NewSession returns a new Mongo Session. | |
func NewSession() testapp.Session { | |
mgoSession, err := mgo.Dial("localhost:27017") | |
if err != nil { | |
panic(err) | |
} | |
return MongoSession{mgoSession} | |
} | |
// MongoSession is currently a Mongo session. | |
type MongoSession struct { | |
*mgo.Session | |
} | |
// DB shadows *mgo.DB to returns a DataLayer interface instead of *mgo.Database. | |
func (s MongoSession) DB(name string) testapp.DataLayer { | |
return &MongoDatabase{Database: s.Session.DB(name)} | |
} | |
// MongoCollection wraps a mgo.Collection to embed methods in models. | |
type MongoCollection struct { | |
*mgo.Collection | |
} | |
func (m MongoCollection) Find(query interface{}) testapp.Query { | |
return &MongoQuery{ | |
Query: m.Collection.Find(query), | |
} | |
} | |
// MongoDatabase wraps a mgo.Database to embed methods in models. | |
type MongoDatabase struct { | |
*mgo.Database | |
} | |
// C shadows *mgo.DB to returns a DataLayer interface instead of *mgo.Database. | |
func (d MongoDatabase) C(name string) testapp.Collection { | |
return MongoCollection{Collection: d.Database.C(name)} | |
} | |
type MongoQuery struct { | |
*mgo.Query | |
} | |
func (q MongoQuery) Apply(change mgo.Change, result interface{}) (info *mgo.ChangeInfo, err error) { | |
return q.Query.Apply(change,result) | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"testapp" | |
"fmt" | |
"testapp/clients" | |
"github.com/pkg/errors" | |
"github.com/globalsign/mgo" | |
"github.com/globalsign/mgo/bson" | |
) | |
var ( | |
session testapp.Session | |
collection testapp.Collection | |
) | |
func init() { | |
session = clients.NewSession() | |
collection = session.DB("CheckoutService").C("order_numbers") | |
} | |
func GetNextNumber() (int, string, error) { | |
doc := bson.M{} | |
change := mgo.Change{ | |
Update: bson.M{"$inc": bson.M{"NextId": 1}}, | |
ReturnNew: true, | |
} | |
query := collection.Find(bson.M{"siteId": "fp-us"}) | |
_, err := query.Apply(change, &doc) | |
if err != nil { | |
return -1, "", errors.New("Could not get an ID from Mongo") | |
} | |
return doc["NextId"].(int), doc["prefix"].(string), nil | |
} | |
func main() { | |
num, prefix, err := GetNextNumber() | |
if err != nil { | |
panic(err) | |
} | |
fmt.Printf("%s%08d\n", prefix, num) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"testing" | |
"testapp/mocks" | |
) | |
func Test_GetNextNumber(t *testing.T) { | |
session = mocks.NewMockSession() | |
collection = session.DB("CheckoutService").C("order_numbers") | |
num, prefix, err := GetNextNumber() | |
if prefix != "FX" { | |
t.Errorf("Error: %s\n", err.Error()) | |
} | |
if num != 9999 { | |
t.Errorf("Error: %d", num) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package testapp | |
import "github.com/globalsign/mgo" | |
// Session is an interface to access to the Session struct. | |
type Session interface { | |
DB(name string) DataLayer | |
Close() | |
} | |
// DataLayer is an interface to access to the database struct. | |
type DataLayer interface { | |
C(name string) Collection | |
} | |
// Collection is an interface to access to the collection struct. | |
type Collection interface { | |
Find(query interface{}) Query | |
} | |
// Query is an interface to access to the Query struct. | |
type Query interface { | |
Apply(change mgo.Change, result interface{}) (info *mgo.ChangeInfo, err error) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package mocks | |
import ( | |
"testapp" | |
"github.com/globalsign/mgo" | |
"github.com/globalsign/mgo/bson" | |
) | |
// MockSession satisfies Session and act as a mock of *mgo.session. | |
type MockSession struct{} | |
// NewMockSession mock NewSession. | |
func NewMockSession() testapp.Session { | |
return MockSession{} | |
} | |
// Close mocks mgo.Session.Close(). | |
func (fs MockSession) Close() {} | |
// DB mocks mgo.Session.DB(). | |
func (fs MockSession) DB(name string) testapp.DataLayer { | |
mockDatabase := MockDatabase{} | |
return mockDatabase | |
} | |
// MockDatabase satisfies DataLayer and act as a mock. | |
type MockDatabase struct{} | |
// MockCollection satisfies Collection and act as a mock. | |
type MockCollection struct{} | |
// Find mock. | |
func (fc MockCollection) Find(query interface{}) testapp.Query { | |
return MockQuery{} | |
} | |
// C mocks mgo.Database(name).Collection(name). | |
func (db MockDatabase) C(name string) testapp.Collection { | |
mockCollection := MockCollection{} | |
return mockCollection | |
} | |
type MockQuery struct{} | |
var ApplyResult = map[string]interface{} { | |
"siteId": "fp-us", | |
"NextId": 9999, | |
"prefix": "FX", | |
} | |
func (mq MockQuery) Apply(change mgo.Change, result interface{}) (info *mgo.ChangeInfo, err error) { | |
*result.(*bson.M) = ApplyResult | |
return &mgo.ChangeInfo{}, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment