Reputation: 111
I can not test the function NewDao
that uses a database arbitrarily. I want to check whether the returned Dao have neither nil client nor nil product.
type Dao struct {
client ClientDao
product ProductDao
}
func (d *Dao) Client() ClientDao {
return d.client
}
func (d *Dao) Product() ProductDao {
return d.product
}
func NewDao(db *sql.DB) (*Dao, error) {
if db == nil {
return nil, errors.New("Can't create a dao from nil database")
}
client, err := newClientDao(db) // Uses db arbitrarily
if err != nil {
return nil, err
}
product, err := newProductDao(db) // Uses db arbitrarily
if err != nil {
return nil, err
}
return &Dao{client, product}, nil
}
I test NewDao()
using sqlmock but it always fails because I don't know what the mock needs to expect.
func TestNewDao(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatal("Can't create database for test dao")
}
// How to set mock to expect anything and never fail?
// mock.ExpectQuery(any) ?
dao, err := NewDao(db)
// err is never nil, because mock has no expectations
if err != nil {
t.Fatal("Can't create dao for test dao.User %q", err)
}
if dao.User() == nil {
t.Fatalf("User dao is nil")
}
if dao.Client() == nil {
t.Fatalf("Client dao is nil")
}
}
Does any one know how to stub the sqlmock for achieving my purpose? Or can appoint an alternative to sqlmock lib?
Upvotes: 1
Views: 409
Reputation: 38343
Your Dao.Client
and Dao.Product
methods themselves make no calls to any dependency and because of that there is nothing for you to mock. There is no point in using a mock for testing these two methods.
And although testing one liners like these may not be the most sensible thing to do, if you want to test them anyway you just need to make sure that the value they return equals the value of the field that they're supposed to return.
func TestDaoClient(t *testing.T) {
var client ClientDao // TODO: prepare a client dao value for test
tests := []struct{
name string
dao *Dao
want ClientDao
}{{
name: "should return client dao",
dao: &Dao{client: client},
want: client,
}, {
name: "should return nil",
dao: &Dao{client: nil},
want: nil,
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.dao.Client(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("client got=%v, want=%v", got, tt.want)
}
})
}
}
Now you can do the same for the Dao.Product
method.
Upvotes: 0
Reputation: 11646
You are missing the second item in your last return in NewDao
:
return &Dao{client, product}
should be:
return &Dao{client, product}, nil
Return statements have to "return" all the things declared in the function header.
Upvotes: 1