Skip to content

Commit 8291398

Browse files
test(mock): complete test coverage (100%) (#100)
* test(finder.mock): complete test coverage (100%) * test(creator.mock): complete test coverage (100%) * test(updater.mock): complete test coverage (100%) * test(deleter.mock): complete test coverage (100%) * test(aggregator.mock): complete test coverage (100%)
1 parent 876b974 commit 8291398

File tree

5 files changed

+1631
-66
lines changed

5 files changed

+1631
-66
lines changed

aggregator/aggregator_test.go

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/stretchr/testify/assert"
2626
"go.mongodb.org/mongo-driver/v2/bson"
2727
"go.mongodb.org/mongo-driver/v2/mongo"
28+
"go.mongodb.org/mongo-driver/v2/mongo/options"
2829
"go.uber.org/mock/gomock"
2930
)
3031

@@ -60,15 +61,6 @@ type IllegalUser struct {
6061
Age string
6162
}
6263

63-
type UpdatedUser struct {
64-
Name string `bson:"name"`
65-
Age int64
66-
}
67-
68-
type UserName struct {
69-
Name string `bson:"name"`
70-
}
71-
7264
func TestAggregator_New(t *testing.T) {
7365
mongoCollection := &mongo.Collection{}
7466
aggregator := NewAggregator[any](mongoCollection, nil, nil)
@@ -82,6 +74,7 @@ func TestAggregator_Aggregation(t *testing.T) {
8274
name string
8375
mock func(ctx context.Context, ctl *gomock.Controller) IAggregator[TestUser]
8476
ctx context.Context
77+
opts []options.Lister[options.AggregateOptions]
8578
want []*TestUser
8679
wantErr assert.ErrorAssertionFunc
8780
}{
@@ -112,14 +105,36 @@ func TestAggregator_Aggregation(t *testing.T) {
112105
},
113106
wantErr: assert.NoError,
114107
},
108+
{
109+
name: "with options - should trigger opts loop",
110+
mock: func(ctx context.Context, ctl *gomock.Controller) IAggregator[TestUser] {
111+
aggregator := mocks.NewMockIAggregator[TestUser](ctl)
112+
aggregator.EXPECT().Aggregate(ctx, gomock.Any()).Return([]*TestUser{
113+
{Name: "chenmingyong", Age: 24},
114+
}, nil).Times(1)
115+
return aggregator
116+
},
117+
ctx: context.Background(),
118+
opts: []options.Lister[options.AggregateOptions]{options.Aggregate().SetComment("test aggregation")},
119+
want: []*TestUser{
120+
{Name: "chenmingyong", Age: 24},
121+
},
122+
wantErr: assert.NoError,
123+
},
115124
}
116125
for _, tc := range testCases {
117126
t.Run(tc.name, func(t *testing.T) {
118127
ctl := gomock.NewController(t)
119128
defer ctl.Finish()
120129
aggregator := tc.mock(tc.ctx, ctl)
121130

122-
result, err := aggregator.Aggregate(tc.ctx)
131+
var result []*TestUser
132+
var err error
133+
if tc.opts != nil {
134+
result, err = aggregator.Aggregate(tc.ctx, tc.opts...)
135+
} else {
136+
result, err = aggregator.Aggregate(tc.ctx)
137+
}
123138
if tc.wantErr(t, err) {
124139
assert.ElementsMatch(t, tc.want, result)
125140
}
@@ -138,6 +153,7 @@ func TestAggregator_AggregateWithParse(t *testing.T) {
138153
name string
139154
mock func(ctx context.Context, ctl *gomock.Controller, result any) IAggregator[TestUser]
140155
ctx context.Context
156+
opts []options.Lister[options.AggregateOptions]
141157
result []*User
142158
want []*User
143159
wantErr assert.ErrorAssertionFunc
@@ -162,10 +178,27 @@ func TestAggregator_AggregateWithParse(t *testing.T) {
162178
},
163179
ctx: context.Background(),
164180
result: []*User{
165-
{Id: "1", Name: "cmy", Age: 24, IsProgrammer: true},
181+
{Id: "1", Name: "chenmingyong", Age: 24, IsProgrammer: true},
182+
},
183+
want: []*User{
184+
{Id: "1", Name: "chenmingyong", Age: 24, IsProgrammer: true},
185+
},
186+
wantErr: assert.NoError,
187+
},
188+
{
189+
name: "with options - should trigger opts loop",
190+
mock: func(ctx context.Context, ctl *gomock.Controller, result any) IAggregator[TestUser] {
191+
aggregator := mocks.NewMockIAggregator[TestUser](ctl)
192+
aggregator.EXPECT().AggregateWithParse(ctx, result, gomock.Any()).Return(nil).Times(1)
193+
return aggregator
194+
},
195+
ctx: context.Background(),
196+
opts: []options.Lister[options.AggregateOptions]{options.Aggregate().SetComment("test aggregation")},
197+
result: []*User{
198+
{Id: "1", Name: "chenmingyong", Age: 25, IsProgrammer: false},
166199
},
167200
want: []*User{
168-
{Id: "1", Name: "cmy", Age: 24, IsProgrammer: true},
201+
{Id: "1", Name: "chenmingyong", Age: 25, IsProgrammer: false},
169202
},
170203
wantErr: assert.NoError,
171204
},
@@ -176,7 +209,12 @@ func TestAggregator_AggregateWithParse(t *testing.T) {
176209
defer ctl.Finish()
177210

178211
aggregator := tc.mock(tc.ctx, ctl, tc.result)
179-
err := aggregator.AggregateWithParse(tc.ctx, tc.result)
212+
var err error
213+
if tc.opts != nil {
214+
err = aggregator.AggregateWithParse(tc.ctx, tc.result, tc.opts...)
215+
} else {
216+
err = aggregator.AggregateWithParse(tc.ctx, tc.result)
217+
}
180218
if tc.wantErr(t, err) {
181219
assert.ElementsMatch(t, tc.want, tc.result)
182220
}

creator/creator_test.go

Lines changed: 199 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ import (
2020
"testing"
2121
"time"
2222

23-
creator "github.com/chenmingyong0423/go-mongox/v2/creator"
23+
"github.com/chenmingyong0423/go-mongox/v2/creator"
2424
mocks "github.com/chenmingyong0423/go-mongox/v2/mock"
2525
"github.com/stretchr/testify/assert"
2626
"github.com/stretchr/testify/require"
2727
"go.mongodb.org/mongo-driver/v2/bson"
2828
"go.mongodb.org/mongo-driver/v2/mongo"
29+
"go.mongodb.org/mongo-driver/v2/mongo/options"
2930
"go.uber.org/mock/gomock"
3031
)
3132

@@ -50,10 +51,10 @@ func (tu *TestUser) DefaultUpdatedAt() {
5051

5152
func TestNewCreator(t *testing.T) {
5253
mongoCollection := &mongo.Collection{}
53-
creator := creator.NewCreator[any](mongoCollection, nil, nil)
54+
c := creator.NewCreator[any](mongoCollection, nil, nil)
5455

55-
assert.NotNil(t, creator)
56-
assert.Equal(t, mongoCollection, creator.GetCollection())
56+
assert.NotNil(t, c)
57+
assert.Equal(t, mongoCollection, c.GetCollection())
5758
}
5859

5960
func TestCreator_One(t *testing.T) {
@@ -62,6 +63,7 @@ func TestCreator_One(t *testing.T) {
6263
mock func(ctx context.Context, ctl *gomock.Controller, doc *TestUser) creator.ICreator[TestUser]
6364
ctx context.Context
6465
doc *TestUser
66+
opts []options.Lister[options.InsertOneOptions]
6567

6668
wantErr error
6769
}{
@@ -89,14 +91,28 @@ func TestCreator_One(t *testing.T) {
8991
Age: 24,
9092
},
9193
},
94+
{
95+
name: "with options - should trigger opts loop",
96+
mock: func(ctx context.Context, ctl *gomock.Controller, doc *TestUser) creator.ICreator[TestUser] {
97+
mockCollection := mocks.NewMockICreator[TestUser](ctl)
98+
mockCollection.EXPECT().InsertOne(ctx, doc, gomock.Any()).Return(&mongo.InsertOneResult{InsertedID: "with_opts"}, nil).Times(1)
99+
return mockCollection
100+
},
101+
ctx: context.Background(),
102+
doc: &TestUser{
103+
Name: "chenmingyong",
104+
Age: 24,
105+
},
106+
opts: []options.Lister[options.InsertOneOptions]{options.InsertOne().SetComment("test")},
107+
},
92108
}
93109
for _, tc := range testCases {
94110
t.Run(tc.name, func(t *testing.T) {
95111
ctl := gomock.NewController(t)
96112
defer ctl.Finish()
97-
creator := tc.mock(tc.ctx, ctl, tc.doc)
113+
c := tc.mock(tc.ctx, ctl, tc.doc)
98114

99-
insertOneResult, err := creator.InsertOne(tc.ctx, tc.doc)
115+
insertOneResult, err := c.InsertOne(tc.ctx, tc.doc, tc.opts...)
100116
require.Equal(t, tc.wantErr, err)
101117
if err == nil {
102118
assert.NotNil(t, insertOneResult.InsertedID)
@@ -111,6 +127,7 @@ func TestCreator_Many(t *testing.T) {
111127
mock func(ctx context.Context, ctl *gomock.Controller, docs []*TestUser) creator.ICreator[TestUser]
112128
ctx context.Context
113129
docs []*TestUser
130+
opts []options.Lister[options.InsertManyOptions]
114131

115132
wantIdsLength int
116133
wantErr error
@@ -143,18 +160,192 @@ func TestCreator_Many(t *testing.T) {
143160
},
144161
wantIdsLength: 2,
145162
},
163+
{
164+
name: "with options - should trigger opts loop",
165+
mock: func(ctx context.Context, ctl *gomock.Controller, docs []*TestUser) creator.ICreator[TestUser] {
166+
mockCollection := mocks.NewMockICreator[TestUser](ctl)
167+
mockCollection.EXPECT().InsertMany(ctx, docs, gomock.Any()).Return(&mongo.InsertManyResult{InsertedIDs: []interface{}{"1", "2"}}, nil).Times(1)
168+
return mockCollection
169+
},
170+
ctx: context.Background(),
171+
docs: []*TestUser{
172+
{Name: "chenmingyong", Age: 24},
173+
{Name: "burt", Age: 25},
174+
},
175+
opts: []options.Lister[options.InsertManyOptions]{options.InsertMany().SetOrdered(false)},
176+
wantIdsLength: 2,
177+
},
146178
}
147179
for _, tc := range testCases {
148180
t.Run(tc.name, func(t *testing.T) {
149181
ctl := gomock.NewController(t)
150182
defer ctl.Finish()
151-
creator := tc.mock(tc.ctx, ctl, tc.docs)
183+
c := tc.mock(tc.ctx, ctl, tc.docs)
152184

153-
insertResult, err := creator.InsertMany(tc.ctx, tc.docs)
185+
insertResult, err := c.InsertMany(tc.ctx, tc.docs, tc.opts...)
154186
require.Equal(t, tc.wantErr, err)
155187
if err == nil {
156188
assert.Equal(t, tc.wantIdsLength, len(insertResult.InsertedIDs))
157189
}
158190
})
159191
}
160192
}
193+
194+
func TestCreator_GetCollection(t *testing.T) {
195+
testCases := []struct {
196+
name string
197+
mock func(ctl *gomock.Controller) creator.ICreator[TestUser]
198+
}{
199+
{
200+
name: "get collection",
201+
mock: func(ctl *gomock.Controller) creator.ICreator[TestUser] {
202+
mockCollection := mocks.NewMockICreator[TestUser](ctl)
203+
expectedCollection := &mongo.Collection{}
204+
mockCollection.EXPECT().GetCollection().Return(expectedCollection).Times(1)
205+
return mockCollection
206+
},
207+
},
208+
}
209+
for _, tc := range testCases {
210+
t.Run(tc.name, func(t *testing.T) {
211+
ctl := gomock.NewController(t)
212+
defer ctl.Finish()
213+
c := tc.mock(ctl)
214+
215+
result := c.GetCollection()
216+
assert.NotNil(t, result)
217+
})
218+
}
219+
}
220+
221+
func TestCreator_ModelHook(t *testing.T) {
222+
testCases := []struct {
223+
name string
224+
mock func(ctl *gomock.Controller) creator.ICreator[TestUser]
225+
226+
modelHook any
227+
}{
228+
{
229+
name: "set model hook",
230+
mock: func(ctl *gomock.Controller) creator.ICreator[TestUser] {
231+
mockCollection := mocks.NewMockICreator[TestUser](ctl)
232+
expectedCreator := mocks.NewMockICreator[TestUser](ctl)
233+
mockCollection.EXPECT().ModelHook(&TestUser{}).Return(expectedCreator).Times(1)
234+
return mockCollection
235+
},
236+
modelHook: &TestUser{},
237+
},
238+
}
239+
for _, tc := range testCases {
240+
t.Run(tc.name, func(t *testing.T) {
241+
ctl := gomock.NewController(t)
242+
defer ctl.Finish()
243+
c := tc.mock(ctl)
244+
245+
result := c.ModelHook(tc.modelHook)
246+
assert.NotNil(t, result)
247+
})
248+
}
249+
}
250+
251+
func TestCreator_RegisterBeforeHooks(t *testing.T) {
252+
testCases := []struct {
253+
name string
254+
mock func(ctl *gomock.Controller) creator.ICreator[TestUser]
255+
256+
hooks []creator.HookFn[TestUser]
257+
}{
258+
{
259+
name: "register before hooks",
260+
mock: func(ctl *gomock.Controller) creator.ICreator[TestUser] {
261+
mockCollection := mocks.NewMockICreator[TestUser](ctl)
262+
expectedCreator := mocks.NewMockICreator[TestUser](ctl)
263+
mockCollection.EXPECT().RegisterBeforeHooks(gomock.Any()).Return(expectedCreator).Times(1)
264+
return mockCollection
265+
},
266+
hooks: []creator.HookFn[TestUser]{
267+
func(ctx context.Context, opCtx *creator.OpContext[TestUser], opts ...any) error {
268+
return nil
269+
},
270+
},
271+
},
272+
{
273+
name: "register multiple before hooks - should trigger hooks loop",
274+
mock: func(ctl *gomock.Controller) creator.ICreator[TestUser] {
275+
mockCollection := mocks.NewMockICreator[TestUser](ctl)
276+
expectedCreator := mocks.NewMockICreator[TestUser](ctl)
277+
mockCollection.EXPECT().RegisterBeforeHooks(gomock.Any(), gomock.Any()).Return(expectedCreator).Times(1)
278+
return mockCollection
279+
},
280+
hooks: []creator.HookFn[TestUser]{
281+
func(ctx context.Context, opCtx *creator.OpContext[TestUser], opts ...any) error {
282+
return nil
283+
},
284+
func(ctx context.Context, opCtx *creator.OpContext[TestUser], opts ...any) error {
285+
return nil
286+
},
287+
},
288+
},
289+
}
290+
for _, tc := range testCases {
291+
t.Run(tc.name, func(t *testing.T) {
292+
ctl := gomock.NewController(t)
293+
defer ctl.Finish()
294+
c := tc.mock(ctl)
295+
296+
result := c.RegisterBeforeHooks(tc.hooks...)
297+
assert.NotNil(t, result)
298+
})
299+
}
300+
}
301+
302+
func TestCreator_RegisterAfterHooks(t *testing.T) {
303+
testCases := []struct {
304+
name string
305+
mock func(ctl *gomock.Controller) creator.ICreator[TestUser]
306+
307+
hooks []creator.HookFn[TestUser]
308+
}{
309+
{
310+
name: "register after hooks",
311+
mock: func(ctl *gomock.Controller) creator.ICreator[TestUser] {
312+
mockCollection := mocks.NewMockICreator[TestUser](ctl)
313+
expectedCreator := mocks.NewMockICreator[TestUser](ctl)
314+
mockCollection.EXPECT().RegisterAfterHooks(gomock.Any()).Return(expectedCreator).Times(1)
315+
return mockCollection
316+
},
317+
hooks: []creator.HookFn[TestUser]{
318+
func(ctx context.Context, opCtx *creator.OpContext[TestUser], opts ...any) error {
319+
return nil
320+
},
321+
},
322+
},
323+
{
324+
name: "register multiple after hooks - should trigger hooks loop",
325+
mock: func(ctl *gomock.Controller) creator.ICreator[TestUser] {
326+
mockCollection := mocks.NewMockICreator[TestUser](ctl)
327+
expectedCreator := mocks.NewMockICreator[TestUser](ctl)
328+
mockCollection.EXPECT().RegisterAfterHooks(gomock.Any(), gomock.Any()).Return(expectedCreator).Times(1)
329+
return mockCollection
330+
},
331+
hooks: []creator.HookFn[TestUser]{
332+
func(ctx context.Context, opCtx *creator.OpContext[TestUser], opts ...any) error {
333+
return nil
334+
},
335+
func(ctx context.Context, opCtx *creator.OpContext[TestUser], opts ...any) error {
336+
return nil
337+
},
338+
},
339+
},
340+
}
341+
for _, tc := range testCases {
342+
t.Run(tc.name, func(t *testing.T) {
343+
ctl := gomock.NewController(t)
344+
defer ctl.Finish()
345+
c := tc.mock(ctl)
346+
347+
result := c.RegisterAfterHooks(tc.hooks...)
348+
assert.NotNil(t, result)
349+
})
350+
}
351+
}

0 commit comments

Comments
 (0)