Golang使用mtest编写mongodb-driver测试

1,277 阅读1分钟

前言

总结下使用官方mongo-go-driver如何编写单元测试

官方的包提供了一个mtest的包去做测试,具体的源码在这里,里面也提供了一些写测试的样例,或者还可以参考go-zeromodel_test.go文件。

下面测试例子使用的是v1.10.1版本的mongo-driver

Action

组织测试代码

func TestUserServiceLogin(t *testing.T) {
    logger := log.NewLogfmtLogger(os.Stderr)

    mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
    defer mt.Close()
    
    mt.Run("register succeed", func(mt *mtest.T) {
        db := mt.DB
        
        // test code here
    })
}) 

Find

查询操作需要mock Cursor的返回值

docs1 := bson.D{
    {Key: "_id", Value: "123"},
    {Key: "username", Value: "pascal"},
    {Key: "password", Value: "fake"},
    {Key: "Nickname", Value: "lin"},
}
docs2 := bson.D{
    {Key: "_id", Value: "123"},
    {Key: "username", Value: "pascal"},
    {Key: "password", Value: "fake"},
    {Key: "Nickname", Value: "lin"},
}
first := mtest.CreateCursorResponse(1, fmt.Sprintf("%s.users", mt.DB.Name()), mtest.FirstBatch, docs1) 
second := mtest.CreateCursorResponse(1, fmt.Sprintf("%s.users", mt.DB.Name()), mtest.NextBatch, docs2) 
killCursors := mtest.CreateCursorResponse(0, fmt.Sprintf("%s.users", mt.DB.Name()), mtest.NextBatch) 
mt.AddMockResponses(first, second, killCursors)

FindOne

no docs

mock一个空的doc,返回ErrNoDocuments

find := mtest.CreateCursorResponse(1, fmt.Sprintf("%s.users", mt.DB.Name()), mtest.FirstBatch)
killCursors := mtest.CreateCursorResponse(0, fmt.Sprintf("%s.users", mt.DB.Name()), mtest.NextBatch)
mt.AddMockResponses(
    find,
    killCursors,
)

with docs

docs := bson.D{
    {Key: "_id", Value: "123"},
    {Key: "username", Value: "pascal"},
    {Key: "password", Value: "fake"},
    {Key: "Nickname", Value: "lin"},
}
mt.AddMockResponses(mtest.CreateCursorResponse(1, fmt.Sprintf("%s.users", mt.DB.Name()), mtest.FirstBatch, docs))

FindOneAndUpdate

docs := bson.D{
    {Key: "_id", Value: "123"},
    {Key: "username", Value: "pascal"},
    {Key: "password", Value: "3858f62230ac3c915f300c664312c63f"},
    {Key: "Nickname", Value: "lin"},
}
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{
    {Key: "ok", Value: 1},
    {Key: "value", Value: docs},
}...))

InsertOne、InsertMany

像一些不需要返回的,可以直接创建一个response就可以

mt.AddMockResponses(mtest.CreateSuccessResponse())

DeleteOne

with docs

mt.AddMockResponses(bson.D{{"ok", 1}, {"acknowledged", true}, {"n", 1}})

no docs

mt.AddMockResponses(bson.D{{"ok", 1}, {"acknowledged", true}, {"n", 0}})