go-sqlmock
go-sqlmock copied to clipboard
write unit test with this
trafficstars
I implement code with dependency injection Like this:
article.go
type IArticleRepo interface {
List() ([]*entity.Article, error)
Detail(id uint) (*entity.Article, error)
Create(item *entity.Article) error
Update(id uint, items map[string]interface{}) error
Delete(ids []uint) error
}
type articleRepo struct {
db container.IDatabaseProvider
}
func (d *articleRepo) List() ([]*entity.Article, error) {
var (
tx = d.db.GetDBSlave()
result []*entity.Article
)
if err := tx.Model(&entity.Article{}).
Find(result).Error; err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
}
return result, nil
}
func (d *articleRepo) Detail(id uint) (*entity.Article, error) {
var (
tx = d.db.GetDBSlave()
result = &entity.Article{}
)
if err := tx.Model(&entity.Article{}).
Where("id = ?", id).
First(result).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("article not found")
}
return nil, err
}
return result, nil
}
func (d *articleRepo) Create(item *entity.Article) error {
var (
tx = d.db.GetDBMain()
)
return tx.Create(item).Error
}
func (d *articleRepo) Update(id uint, items map[string]interface{}) error {
var (
tx = d.db.GetDBMain()
)
if err := tx.Model(&entity.Article{}).
Where("id = ?", id).
Updates(items).Error; err != nil {
}
if tx.RowsAffected == 0 {
tx.Rollback()
return errors.New("article not found")
}
return nil
}
func (d *articleRepo) Delete(ids []uint) error {
var (
tx = d.db.GetDBMain()
)
return tx.Delete(&entity.Article{}, ids).Error
}
func NewArticleRepo(db container.IDatabaseProvider) IArticleRepo {
return &articleRepo{
db: db,
}
}
and my file test article_test.go
type MockDatabaseProvider struct{}
func (m *MockDatabaseProvider) GetDBSlave() *gorm.DB {
mockDb, _, _ := sqlmock.New()
dialector := postgres.New(postgres.Config{
Conn: mockDb,
DriverName: "postgres",
})
db, _ := gorm.Open(dialector, &gorm.Config{})
return db
}
func (m *MockDatabaseProvider) GetDBMain() *gorm.DB {
mockDb, _, _ := sqlmock.New()
dialector := postgres.New(postgres.Config{
Conn: mockDb,
DriverName: "postgres",
})
db, _ := gorm.Open(dialector, &gorm.Config{})
return db
}
func TestArticleRepo_Create(t *testing.T) {
mockDB := &MockDatabaseProvider{}
// Create a test article
testArticle := &entity.Article{
Title: "Test Article",
Author: "Author",
}
repo := NewArticleRepo(mockDB)
err := repo.Create(testArticle)
assert.Nil(t, err)
}
=== RUN TestArticleRepo_Create article_test.go:53: Error Trace: /Users/macthinh/project/my-template-with-go/internal/data/article_test.go:53 Error: Expected nil, but got: &errors.errorString{s:"all expectations were already fulfilled, call to database transaction Begin was not expected"} Test: TestArticleRepo_Create --- FAIL: TestArticleRepo_Create (8.79s)
What am I missing?