mongodbgomockingmongo-driver

Go mongo-driver mtest, FindOne doesn't return correct result based on given filter


I have a function which should return based on filter from mongodb a org, which in reality works fine.

func (m *MongoSysService) GetOrg(org string) (types.Org, error) {
    var data types.Org
    if err := m.org.FindOne(context.Background(), bson.D{{Key: "_id", Value: org}}).Decode(&data); err != nil {
        return types.Org{}, err
    }
    return data, nil
}

But then I try to mock it using mtest and what happens is that it always returns 1st result org1, no matter how I tried, can't figure out what's wrong.

func TestMongoSysService_GetOrg(t *testing.T) {
    mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
    defer mt.Close()

    mt.Run("success", func(mt *mtest.T) {
        mongoDB.org = mt.Coll

        first := mtest.CreateCursorResponse(1, "foo.bar", mtest.FirstBatch, bson.D{
            {Key: "_id", Value: "org1"},
            {Key: "name", Value: "org1"},
            {Key: "api", Value: "key1"},
        })

        second := mtest.CreateCursorResponse(2, "foo.bar", mtest.NextBatch, bson.D{
            {Key: "_id", Value: "org2"},
            {Key: "name", Value: "org2"},
            {Key: "api", Value: "key2"},
        })

        third := mtest.CreateCursorResponse(3, "foo.bar", mtest.NextBatch, bson.D{
            {Key: "_id", Value: "org3"},
            {Key: "name", Value: "org3"},
            {Key: "api", Value: "key3"},
        })

        killCursors := mtest.CreateCursorResponse(0, "foo.bar", mtest.NextBatch)

        mt.AddMockResponses(first, second, third, killCursors)

        result, err := mongoDB.GetOrg("org2")
        if err != nil {
            t.Fatal(err)
        }
        if result.Name != "org2" || result.GoogleAPIKey != "key2" {
            t.Errorf("Expected %s and %s, got %s and %s", "org2", "key2", result.Name, result.GoogleAPIKey)
        }
    })
}

Using the same test case I tried to use Find on cursor to find all records, it works in mock, I get all 3 records when mocking it on Find.

What could be the issue here?

I'm using go.mongodb.org/mongo-driver v1.5.4 and go1.9


Solution

  • I think you are misunderstanding how a mock works - you're not saying "here's the data, now act like a database", you are saying "here's how to act like a database". When you have

    first := mtest.CreateCursorResponse(1, "foo.bar", mtest.FirstBatch, bson.D{
        {Key: "_id", Value: "org1"},
        {Key: "name", Value: "org1"},
        {Key: "api", Value: "key1"},
    })
    

    You are saying "the first thing we get back from the collection will be org1." You are not saying "there is some data called org1 and send it back if the query matches."

    If you want org2 to be the response, then you need to tell it to send back org2 as the first response.