1
2
3
4
5
6
7 package integration
8
9 import (
10 "context"
11 "testing"
12
13 "go.mongodb.org/mongo-driver/bson"
14 "go.mongodb.org/mongo-driver/bson/bsoncodec"
15 "go.mongodb.org/mongo-driver/internal/assert"
16 "go.mongodb.org/mongo-driver/mongo"
17 "go.mongodb.org/mongo-driver/mongo/integration/mtest"
18 "go.mongodb.org/mongo-driver/mongo/options"
19 )
20
21
22 type finder interface {
23 FindOne(ctx context.Context, filter interface{}, opts ...*options.FindOneOptions) *mongo.SingleResult
24 Find(context.Context, interface{}, ...*options.FindOptions) (*mongo.Cursor, error)
25 }
26
27
28 type mockFinder struct {
29 docs []interface{}
30 err error
31 registry *bsoncodec.Registry
32 }
33
34
35 func (mf *mockFinder) FindOne(_ context.Context, _ interface{}, _ ...*options.FindOneOptions) *mongo.SingleResult {
36 return mongo.NewSingleResultFromDocument(mf.docs[0], mf.err, mf.registry)
37 }
38
39
40 func (mf *mockFinder) Find(context.Context, interface{}, ...*options.FindOptions) (*mongo.Cursor, error) {
41 return mongo.NewCursorFromDocuments(mf.docs, mf.err, mf.registry)
42 }
43
44
45 type ShopItem struct {
46 ID int `bson:"id"`
47 Price float64 `bson:"price"`
48 }
49
50
51 func getItem(f finder, id int) (*ShopItem, error) {
52 res := f.FindOne(context.Background(), bson.D{{"id", id}})
53 var item ShopItem
54 err := res.Decode(&item)
55 return &item, err
56 }
57
58
59 func getItems(f finder) ([]ShopItem, error) {
60 cur, err := f.Find(context.Background(), bson.D{})
61 if err != nil {
62 return nil, err
63 }
64
65 var items []ShopItem
66 err = cur.All(context.Background(), &items)
67 return items, err
68 }
69
70 func TestMockFind(t *testing.T) {
71 mt := mtest.New(t, mtest.NewOptions().CreateClient(false))
72
73 insertItems := []interface{}{
74 ShopItem{ID: 0, Price: 1.5},
75 ShopItem{ID: 1, Price: 5.7},
76 ShopItem{ID: 2, Price: 0.25},
77 }
78 insertItem := []interface{}{ShopItem{ID: 1, Price: 5.7}}
79
80 mt.Run("mongo.Collection can be passed as interface", func(mt *mtest.T) {
81
82 _, err := mt.Coll.InsertMany(context.Background(), insertItems)
83 assert.Nil(mt, err, "InsertMany error: %v", err)
84
85
86 shopItem, err := getItem(mt.Coll, 1)
87 assert.Nil(mt, err, "getItem error: %v", err)
88 assert.Equal(mt, 1, shopItem.ID)
89 assert.Equal(mt, 5.7, shopItem.Price)
90
91
92 shopItems, err := getItems(mt.Coll)
93 assert.Nil(mt, err, "getItems error: %v", err)
94 for i, shopItem := range shopItems {
95 expectedItem := insertItems[i].(ShopItem)
96 assert.Equal(mt, expectedItem.ID, shopItem.ID)
97 assert.Equal(mt, expectedItem.Price, shopItem.Price)
98 }
99 })
100
101 mt.Run("FindOne can be mocked", func(mt *mtest.T) {
102
103 mf := &mockFinder{docs: insertItem, err: nil, registry: nil}
104
105
106 shopItem, err := getItem(mf, 1)
107 assert.Nil(mt, err, "getItem error: %v", err)
108 assert.Equal(mt, 1, shopItem.ID)
109 assert.Equal(mt, 5.7, shopItem.Price)
110 })
111
112 mt.Run("Find can be mocked", func(mt *mtest.T) {
113
114 mf := &mockFinder{docs: insertItems, err: nil, registry: nil}
115
116
117 shopItems, err := getItems(mf)
118 assert.Nil(mt, err, "getItems error: %v", err)
119 for i, shopItem := range shopItems {
120 expectedItem := insertItems[i].(ShopItem)
121 assert.Equal(mt, expectedItem.ID, shopItem.ID)
122 assert.Equal(mt, expectedItem.Price, shopItem.Price)
123 }
124 })
125 }
126
View as plain text