我正在尝试模拟 mongoDB 函数
Aggregate
,但它不断返回command failed
的一般错误。
如果有人感兴趣,有一个关于其他功能以及如何模拟它们的好博客Mock mongo-go-driver。
功能正在测试中
func (b *BlogsRepo) CountTagsInBlogs(ctx context.Context) (map[string]int, error) {
clog := log.GetLoggerFromContext(ctx)
// Specify the pipeline to group and count tags
pipeline := []bson.M{
{
"$unwind": "$tags",
},
{
"$group": bson.M{
"_id": "$tags",
"count": bson.M{"$sum": 1},
},
},
}
// Aggregate the data based on the pipeline
cursor, err := b.collection.Aggregate(ctx, pipeline)
if err != nil {
clog.ErrorCtx(err, log.Ctx{
"msg": "Error aggregating data",
"err": err,
})
return nil, err
}
defer cursor.Close(ctx)
// Create a map to store tag counts
tagCounts := make(map[string]int)
// Iterate through the results and populate the map
for cursor.Next(ctx) {
var result struct {
Tag string `bson:"_id"`
Count int `bson:"count"`
}
if err := cursor.Decode(&result); err != nil {
clog.ErrorCtx(err, log.Ctx{
"msg": "Error decoding result"},
)
return nil, err
}
tagCounts[result.Tag] = result.Count
}
return tagCounts, nil
}
测试
func TestBlogsRepo_CountTagsInBlogs(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
defer mt.Close()
ctx := context.TODO()
testCases := []struct {
name string
mockedResponse []bson.D
expected map[string]int
err error
}{
{
name: "successful count tags response",
mockedResponse: []bson.D{
{{"_id", "java"}, {"count", 3}},
{{"_id", "go"}, {"count", 7}},
{{"_id", "kotlin"}, {"count", 3}},
},
expected: map[string]int{
"java": 3,
"go": 7,
"kotlin": 3,
},
err: nil,
},
}
for _, tc := range testCases {
tc := tc
mt.Run(tc.name, func(mt *mtest.T) {
// Mock the aggregation response
mt.AddMockResponses(tc.mockedResponse...)
blogRepo := NewBlogRepository(mt.Client, mt.Coll)
// Call the method being tested
tagCounts, err := blogRepo.CountTagsInBlogs(ctx)
// Check the returned values against the expected values
assert.Equal(t, tc.expected, tagCounts, "Tag counts do not match expected values")
assert.NoError(t, err)
})
}
}
错误:
Error: Received unexpected error:
command failed
Test: TestBlogsRepo_CountTagsInBlogs
还有第二个错误,但这只是因为错误被捕获,返回的地图是
nil
,与预期结果不符。
错误发生在这里
cursor, err := b.collection.Aggregate(ctx, pipeline)
if err != nil {
clog.ErrorCtx(err, log.Ctx{
"msg": "Error aggregating data",
"err": err,
})
return nil, err
}
defer cursor.Close(ctx)
模拟看起来正确。任何建议将不胜感激。
Collection.Aggregate()
调用的响应,您必须使用 mtest.CreateCursorResponse()
创建和使用光标响应。
所以这样做:
for i, tc := range testCases {
tc := tc
mt.Run(tc.name, func(mt *mtest.T) {
// Mock the aggregation response
mt.AddMockResponses(mtest.CreateCursorResponse(
0,
fmt.Sprintf("%s.%d", tc.name, i),
mtest.FirstBatch,
tc.mockedResponse...,
))