In PHP development, you may encounter problems when using MockDB (a MockDB type variable) as the gorm.DB value in the structure. In this case, MockDB cannot be directly assigned to gorm.DB. This may cause the code to fail to compile or cause runtime errors. Regarding this problem, PHP editor Xigua suggested using other methods to deal with it, such as using type conversion or redesigning the code logic to ensure that the gorm.DB value in the structure can be assigned correctly. Using the correct method to handle this problem can avoid unnecessary errors and exceptions and improve the reliability and stability of the code.
I have created a get function to get exercises from a postgres database. I wrote a mock test but I get this error from the structure, how can I fix it?
I used the handler structure, which has a *gorm.db structure.
mistake:
Cannot use mockdb (*mockdb type variable) as the *gorm.db value in the structure literal
// router package exercises import ( "github.com/gin-gonic/gin" "gorm.io/gorm" ) type handlers struct { db *gorm.db } func registerroutes(router *gin.engine, db *gorm.db) { h := &handlers{ db: db, } routes := router.group("/exercises") routes.post("/", h.addexercise) routes.get("/", h.getexercises) routes.get("/:id", h.getexercise) routes.put("/:id", h.updateexercise) routes.delete("/:id", h.deleteexercise) }
// test package exercises import ( "net/http" "net/http/httptest" "testing" "github.com/gin-gonic/gin" "github.com/kayraberktuncer/sports-planner/pkg/common/models" "github.com/stretchr/testify/mock" "gorm.io/gorm" ) type MockDB struct { mock.Mock } func (m *MockDB) Find(value interface{}) *gorm.DB { args := m.Called(value) return args.Get(0).(*gorm.DB) } func (m *MockDB) Error() error { args := m.Called() return args.Error(0) } func TestGetExercises(t *testing.T) { // Setup mock DB mockDB := new(MockDB) mockDB.On("Find", &[]models.Exercise{}).Return(mockDB).Once() // Setup Gin router router := gin.New() router.GET("/", func(c *gin.Context) { handlers := &Handlers{DB: mockDB} // error handlers.GetExercises(c) }) // Perform request w := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/", nil) router.ServeHTTP(w, req) // Assert response if w.Code != http.StatusOK { t.Errorf("Expected status code %d, got %d", http.StatusOK, w.Code) } // Assert mock DB was called correctly mockDB.AssertExpectations(t) }
I want to use my handler structure for mock testing
mockdb
and gorm's db
are two different structures, you cannot use them interchangeably. If they implement the same interface, they can be used in the same place. For example:
// router package exercises import ( "github.com/gin-gonic/gin" "gorm.io/gorm" ) // this interface will be implemented by gorm.DB struct type Store interface { Create(value interface{}) *gorm.DB First(out interface{}, where ...interface{}) *gorm.DB Model(value interface{}) *gorm.DB Delete(value interface{}, where ...interface{}) *gorm.DB Find(out interface{}, where ...interface{}) *gorm.DB DB() *sql.DB Raw(sql string, values ...interface{}) *gorm.DB Exec(sql string, values ...interface{}) *gorm.DB Where(query interface{}, args ...interface{}) *gorm.DB //other method signatures } type Handlers struct { DB Store } func RegisterRoutes(router *gin.Engine, db Store) { h := &Handlers{ DB: db, } routes := router.Group("/exercises") routes.POST("/", h.AddExercise) routes.GET("/", h.GetExercises) routes.GET("/:id", h.GetExercise) routes.PUT("/:id", h.UpdateExercise) routes.DELETE("/:id", h.DeleteExercise) }
Now you can pass *gorm.db
to the registerroutes
function in your code. For testing purposes, a mockdb
structure can be used if it implements all methods in the store
interface.
The above is the detailed content of Unable to use mockDB (variable of type *MockDB) as *gorm.DB value in struct literal. For more information, please follow other related articles on the PHP Chinese website!