Closed mrdulin closed 3 months ago
database/sql.Result
and database/sql/driver.Result
are interfaces. They expose the same methods. So they are the same.
DeepEqual
checks deeply that the concrete types are the same. But as you are dealing with interfaces, that's not what matters for your unit test. Instead you are just interested in checking that the values returned by each method are what you expect:
id1, err1 := got.LastInsertId()
id2, err2 := tt.want.LastInsertId()
switch {
case err1 != nil:
if err2 == nil || err2.Error() != err1.Error() {
t.Fatalf("LastInsertId: error mismatch %q vs %q", err1, err2)
}
case err2 != nil:
t.Fatalf("LastInsertId: error mismatch nil vs %q", err2)
case id1 != id2:
t.Fatal("LastInsertId: id mismatch %d vs %d", id1, id2)
}
// Same for RowsAffected
My code above can be refactored:
check := func(m string, f1 func() (int64, error), f2 func() (int64, error)) {
v1, err1 := f1()
v2, err2 := f2()
switch {
case err1 != nil:
if err2 == nil || err2.Error() != err1.Error() {
t.Fatalf(m+": error mismatch %q vs %q", err1, err2)
}
case err2 != nil:
t.Fatalf(m+": error mismatch nil vs %q", err2)
case v1 != v2:
t.Fatal(m+": id mismatch %d vs %d", v1, v2)
}
}
check("LastInsertId", got.LastInsertId, tt.want.LastInsertId)
check("RowsAffected", got.RowsAffected, tt.want.RowsAffected)
I am not clearly how it works sqlmock internal. Here is my case:
A insert function:
As you can see, the return value of this function is
sql.Result
anderror
.After I add below statements in my unit test, this test failed.
Got error:
I mock the return result using
WillReturnResult(sqlmock.NewResult(1, 1))
. And the value oftt.want
issqlmock.NewResult(1, 1)
as well.The return value of
sqlmock.NewResult
isdriver.Result
, so I think that's why the error happened.Is it necessary add
!reflect.DeepEqual(got, tt.want)
and assert it ? Or, all I need ismock.ExpectationsWereMet()
? Thanks for explaining.