Home > Enterprise >  httptest.NewRequest issues with query parameters
httptest.NewRequest issues with query parameters

Time:08-12

I'm using the GIN framework with a Postgres DB and GORM as an ORM.

One of the routes accepts query parameters. When I search for this in my browser, I get the expected results: an array of json objects. Here is the route: /artworks/?limit=10&last_id=1

However, when I try to test the handler used by that route, I get the following error: routes_test.go:184: [ERROR] Unable to unmarshal data to artworks: json: cannot unmarshal object into Go value of type []models.Artwork

The query that the ORM is trying to run in the test function is the folowing: SELECT * FROM "artwork_migrate_artwork" WHERE id = ''

So when I run the request in the browser, it properly pulls the query parameters and then the ORM runs the proper sql query. But when using httptest.NewRequest it seems like the query parameters are not used.

Here is my test function:

func TestGetArtworks(t *testing.T) {
    dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=%s TimeZone=%s", env_var.Host, env_var.User, env_var.Password, env_var.DBname, env_var.Port, env_var.SSLMODE, env_var.TimeZone)
    db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("failed to connect to db")
    }

    route := "/artworks/"
    handler := handlers.GetArtwork(db)
    router := setupGetRouter(handler, route)
    writer := httptest.NewRecorder()
    req := httptest.NewRequest(http.MethodGet, "/artworks/?limit=10&last_id=1", nil)
    fmt.Println(req)
    router.ServeHTTP(writer, req)

    assert.Equal(t, 200, writer.Code)

    data, err := ioutil.ReadAll(writer.Body)
    if err != nil {
        t.Errorf("\u001b[31m[Error] Unable to read writer.Body: %s", err)
    }

    // no body can be unmarshalled
    fmt.Println("Here is the body:", writer.Body.String())

    var artworks []models.Artwork
    if err := json.Unmarshal(data, &artworks); err != nil {
        t.Errorf("\u001b[31m[ERROR] Unable to unmarshal data to artworks: %s", err)
    }

    assert.Equal(t, 10, len(artworks))
}

Here is my route handler:

func GetArtworks(db *gorm.DB) gin.HandlerFunc {
    return func(c *gin.Context) {
        limit, err := strconv.Atoi(c.Query("limit"))
        if err != nil {
            panic(err)
        }
        last_id := c.Query("last_id")

        var artworks []models.Artwork
        db.Where("id > ?", last_id).Limit(limit).Find(&artworks)

        c.JSON(http.StatusOK, artworks)
    }
}
router.GET("/artworks", han.GetArtworks(db))

Here is the model struct:

type Artwork struct {
    ID              int       `json:"id"`
    Title           string    `json:"title"`
    Nationality     string    `json:"nationality"`
    Artist_Bio      string    `json:"artist_bio"`
    Desc            string    `json:"desc"`
    Culture         string    `json:"culture"`
    Gender          string    `json:"gender"`
    Nation          string    `json:"nation"`
    Medium          string    `json:"medium"`
    Date_of_Release string    `json:"date_of_release"`
    Image           string    `json:"image"`
    Image_Small     string    `json:"image_small"`
    Last_Modified   time.Time `json:"last_modified"`
    Artist_ID       int       `json:"artist_id"`
    Source_ID       int       `json:"source_id"`
}

CodePudding user response:

@Brits is correct: It was due to a misspelled handler

handler := handlers.GetArtwork(db)

should have been handler := handlers.GetArtworks(db)

  • Related