HI All,
I was tried to create unit test for my below service but not able to mock the GORM db. Could you please help on that.
Service :
package services
import (
“errors”
errorsconstant “paymentpoc/errors”
“paymentpoc/models”“Gorm”
)func ProcessCreditTransaction(req models.PaymentRequest, DB *gorm.DB) error {
var payee models.Payee
if err := DB.Where(“payee_id = ?”, req.PayeeID).First(&payee).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return errorsconstant.ErrPayerNotFound
}
return err
}payee.Balance += req.Amount
if err := DB.Save(&payee).Error; err != nil {
return err
}return nil
}
Uni Test :
package services
import (
“testing”errorsconstant “paymentpoc/errors”
“paymentpoc/models”“/stretchr/testify/assert”
“/stretchr/testify/suite”
“gorm/driver/sqlite”
“gorm/gorm”
_ “modernc.org/sqlite”
)type ServicesSuite struct {
suite.Suite
DB *gorm.DB
}func (suite *ServicesSuite) SetupTest() {
var err error
suite.DB, err = gorm.Open(sqlite.Open(“file::memory:?cache=shared”), &gorm.Config{})
if err != nil {
suite.T().Fatal(“Failed to connect to database:”, err)
}// Auto migrate the schema
err = suite.DB.AutoMigrate(&models.Payee{})
if err != nil {
suite.T().Fatal(“Failed to migrate database:”, err)
}
}func (suite *ServicesSuite) TearDownTest() {
// Clean up the database after each test
db, _ := suite.DB.DB()
db.Close()
}func TestServicesSuite(t *testing.T) {
suite.Run(t, new(ServicesSuite))
}func (suite *ServicesSuite) TestProcessCreditTransaction_Success() {
// Arrange
payee := models.Payee{
ID: “123”, // UseID
instead ofPayeeID
Balance: 100.0,
}
suite.DB.Create(&payee)req := models.PaymentRequest{PayeeID: “123”, Amount: 50.0}
// Act
err := ProcessCreditTransaction(req, suite.DB)// Assert
assert.NoError(suite.T(), err)var updatedPayee models.Payee
// Change to useid
instead ofpayee_id
suite.DB.First(&updatedPayee, “id = ?”, “123”)
assert.Equal(suite.T(), 150.0, updatedPayee.Balance) // Expect updated balance to be 150
}func (suite *ServicesSuite) TestProcessCreditTransaction_PayeeNotFound() {
// Arrange
req := models.PaymentRequest{PayeeID: “nonexistent”, Amount: 50.0}// Act
err := ProcessCreditTransaction(req, suite.DB)// Assert
assert.Error(suite.T(), err)
assert.Equal(suite.T(), errorsconstant.ErrPayerNotFound, err)
}