亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Go 中模擬 MongoDB 響應

在 Go 中模擬 MongoDB 響應

Go
慕妹3146593 2023-06-26 17:32:59
我正在從 MongoDB 獲取文檔并將其傳遞給函數transform,例如var doc map[string]interface{}err := collection.FindOne(context.TODO(), filter).Decode(&doc) result := transform(doc)我想為 編寫單元測試transform,但我不確定如何模擬來自 MongoDB 的響應。理想情況下我想設置這樣的東西:func TestTransform(t *testing.T) {    byt := []byte(`    {"hello": "world",     "message": "apple"} `)    var doc map[string]interface{}    >>> Some method here to Decode byt into doc like the code above <<<    out := transform(doc)    expected := ...    if diff := deep.Equal(expected, out); diff != nil {        t.Error(diff)    }}一種方法是json.Unmarshalinto doc,但這有時會產生不同的結果。例如,如果 MongoDB 中的文檔中有一個數組,那么該數組將被解碼為doc類型bson.A而不是[]interface{}類型。
查看完整描述

3 回答

?
郎朗坤

TA貢獻1921條經驗 獲得超9個贊

我認為您可以嘗試類似以下的操作(當然,您可能需要對此進行調整和實驗):

func TestTransform(t *testing.T) {

? ? mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))

? ? defer mt.Close()


? ? mt.Run("find & transform", func(mt *mtest.T) {

? ? ? ? myollection = mt.Coll

? ? ? ? expected := myStructure{...}


? ? ? ? mt.AddMockResponses(mtest.CreateCursorResponse(1, "foo.bar", mtest.FirstBatch, bson.D{

? ? ? ? ? ? {"_id", expected.ID},

? ? ? ? ? ? {"field-1", expected.Field1},

? ? ? ? ? ? {"field-2", expected.Field2},

? ? ? ? }))


? ? ? ? response, err := myFindFunction(expected.ID)

? ? ? ? if err != nil {

? ? ? ? ? ? t.Error(err)

? ? ? ? }


? ? ? ? out := transform(response)

? ? ? ? if diff := deep.Equal(expected, out); diff != nil {

? ? ? ? ? ? t.Error(diff)

? ? ? ? }

? ? })

}

或者,您可以通過與 Docker 容器的集成測試以自動化的方式執行更真實的測試。

查看完整回答
反對 回復 2023-06-26
?
萬千封印

TA貢獻1891條經驗 獲得超3個贊

編寫可測試的最佳解決方案可能是將代碼提取到 DAO 或數據存儲庫。您將定義一個接口來返回您需要的內容。這樣,您就可以使用模擬版本進行測試。


// repository.go

type ISomeRepository interface {

? ? Get(string) (*SomeModel, error)

}


type SomeRepository struct { ... }


func (r *SomeRepository) Get(id string) (*SomeModel, error) {

? ? // Handling a real repository access and returning your Object

}

當你需要模擬它時,只需創建一個 Mock-Struct 并實現接口:


// repository_test.go


type SomeMockRepository struct { ... }


func (r *SomeRepository) Get(id string) (*SomeModel, error) {

? ? return &SomeModel{...}, nil

}


func TestSomething() {

? ? // You can use your mock as ISomeRepository

? ? var repo *ISomeRepository

? ? repo = &SomeMockRepository{}

? ? someModel, err := repo.Get("123")

}

這最好與某種依賴注入一起使用,因此將此存儲庫作為 ISomeRepository 傳遞到函數中。



查看完整回答
反對 回復 2023-06-26
?
胡說叔叔

TA貢獻1804條經驗 獲得超8個贊

使用 Monkey 庫來掛鉤 mongo 驅動程序中的任何函數。


例如:


func insert(collection *mongo.Collection) (int, error) {

    ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)


    u := User{

        Name: "kevin",

        Age:  20,

    }


    res, err := collection.InsertOne(ctx, u)

    if err != nil {

        log.Printf("error: %v", err)

        return 0, err

    }


    id := res.InsertedID.(int)

    return id, nil

}


func TestInsert(t *testing.T) {

    var c *mongo.Collection


    var guard *monkey.PatchGuard

    guard = monkey.PatchInstanceMethod(reflect.TypeOf(c), "InsertOne",

        func(c *mongo.Collection, ctx context.Context, document interface{}, opts ...*options.InsertOneOptions) (*mongo.InsertOneResult, error) {

            guard.Unpatch()

            defer guard.Restore()


            log.Printf("record: %+v, collection: %s, database: %s", document, c.Name(), c.Database().Name())

            res := &mongo.InsertOneResult{

                InsertedID: 100,

            }


            return res, nil

        })


    collection := client.Database("db").Collection("person")

    id, err := insert(collection)


    require.NoError(t, err)

    assert.Equal(t, id, 100)

}


查看完整回答
反對 回復 2023-06-26
  • 3 回答
  • 0 關注
  • 241 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號