Home > Backend Development > Golang > Unable to use mockDB (variable of type *MockDB) as *gorm.DB value in struct literal

Unable to use mockDB (variable of type *MockDB) as *gorm.DB value in struct literal

WBOY
Release: 2024-02-14 22:10:08
forward
785 people have browsed it

Unable to use mockDB (variable of type *MockDB) as *gorm.DB value in struct literal

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.

Question content

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)
}
Copy after login
// 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)
}
Copy after login

I want to use my handler structure for mock testing

Solution

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)
}
Copy after login

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!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template