Search code examples
mongodbunit-testinggobson

bson.M {} deepequal does not seem to hande int32


I have a function for comparing two structs and making a bson document as input to mongodb updateOne()

Example struct format

type event struct {
    ...
    Name           string
    StartTime      int32
    ... 
}

Diff function, please ignore that I have not checked for no difference yet.

func diffEvent(e event, u event) (bson.M, error) {
    newValues := bson.M{}       
    if e.Name != u.Name {
        newValues["name"] = u.Name      
    }

    if e.StartTime != u.StartTime {
        newValues["starttime"] = u.StartTime        
    }

    ... 
    return bson.M{"$set": newValues}, nil   
}

Then I generated a test function like so:

func Test_diffEvent(t *testing.T) {
    type args struct {
        e event
        u event
    }
    tests := []struct {
        name    string
        args    args
        want    bson.M
        wantErr bool
    }{      
        {
            name: "update startime",
            args: args{
                e: event{StartTime: 1},
                u: event{StartTime: 2},
            },
            want:    bson.M{"$set": bson.M{"starttime": 2}},
            wantErr: false,
        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got, err := diffEvent(tt.args.e, tt.args.u)
            if (err != nil) != tt.wantErr {
                t.Errorf("diffEvent() error = %v, wantErr %v", err, tt.wantErr)
                return
            }
            if !reflect.DeepEqual(got, tt.want) {
                t.Errorf("diffEvent() = %v, want %v", got, tt.want)
            }
        })
    }
}

This fails with a

 --- FAIL: Test_diffEvent/update_startime (0.00s)
        models_test.go:582: diffEvent() = map[$set:map[starttime:2]], want map[$set:map[starttime:2]]

For me this seem to be the same. I have played around with this and bool fields, string fields, enum fields, and fields as struct or fields as arrays of structs seems to work fine with deepequal, but it gives an error for int32 fields.

As a go beginner; what am I missing here? I would assume that if bool/string works then int32 would too.


Solution

  • This:

    bson.M{"starttime": 2}
    

    Sets the "starttime" key to the value of the literal 2. 2 is an untyped integer constant, and since no type is provided, its default type will be used which is int.

    And 2 values stored in interface values are only equal if the dynamic value stored in them have identical type and value. So a value 2 with int type cannot be equal to a value 2 of type int32.

    Use explicit type to tell you want to specify a value of int32 type:

    bson.M{"starttime": int32(2)}