Repository: gin-gonic/gin
Pull request #2848 (2021-08-30 16:21:31)

gin.Context.SetParam shortcut for e2e tests
While writing e2e tests I noticed that adding path params can be simplified further. 
Instead of appending params to the gin context like this:
`c.Params = append(c.Params, Param{Key: key,Value: value})`
The function `SetParam` will do the same but increase usability for writing e2e tests.


Patch:
diff --git a/.github/workflows/gin.yml b/.github/workflows/gin.yml
index 21895f2..6eb5a64 100644
--- a/.github/workflows/gin.yml
+++ b/.github/workflows/gin.yml
@@ -21,13 +21,13 @@ jobs:
       - name: Setup golangci-lint
         uses: golangci/golangci-lint-action@v2
         with:
-          version: v1.42.0
+          version: v1.42.1
           args: --verbose
   test:
     strategy:
       matrix:
         os: [ubuntu-latest, macos-latest]
-        go: [1.13, 1.14, 1.15, 1.16]
+        go: [1.13, 1.14, 1.15, 1.16, 1.17]
         test-tags: ['', nomsgpack]
         include:
           - os: ubuntu-latest
diff --git a/context.go b/context.go
index 56c20f2..6284948 100644
--- a/context.go
+++ b/context.go
@@ -383,6 +383,15 @@ func (c *Context) Param(key string) string {
 	return c.Params.ByName(key)
 }
 
+// AddParam adds param to context and
+// replaces path param key with given value for e2e testing purposes
+// Example Route: "/user/:id"
+// AddParam("id", 1)
+// Result: "/user/1"
+func (c *Context) AddParam(key, value string) {
+	c.Params = append(c.Params, Param{Key: key, Value: value})
+}
+
 // Query returns the keyed url query value if it exists,
 // otherwise it returns an empty string `("")`.
 // It is shortcut for `c.Request.URL.Query().Get(key)`
diff --git a/go.mod b/go.mod
index bf68259..26b9271 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ go 1.13
 require (
 	github.com/gin-contrib/sse v0.1.0
 	github.com/go-playground/validator/v10 v10.9.0
-	github.com/goccy/go-json v0.7.6
+	github.com/goccy/go-json v0.7.8
 	github.com/json-iterator/go v1.1.11
 	github.com/mattn/go-isatty v0.0.13
 	github.com/stretchr/testify v1.7.0
diff --git a/go.sum b/go.sum
index 351ee25..8aaf41a 100644
--- a/go.sum
+++ b/go.sum
@@ -12,8 +12,8 @@ github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/j
 github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
 github.com/go-playground/validator/v10 v10.9.0 h1:NgTtmN58D0m8+UuxtYmGztBJB7VnPgjj221I1QHci2A=
 github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
-github.com/goccy/go-json v0.7.6 h1:H0wq4jppBQ+9222sk5+hPLL25abZQiRuQ6YPnjO9c+A=
-github.com/goccy/go-json v0.7.6/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/goccy/go-json v0.7.8 h1:CvMH7LotYymYuLGEohBM1lTZWX4g6jzWUUl2aLFuBoE=
+github.com/goccy/go-json v0.7.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=


Test patch:
diff --git a/context_1.16_test.go b/context_1.16_test.go
new file mode 100644
index 0000000..053e6c5
--- /dev/null
+++ b/context_1.16_test.go
@@ -0,0 +1,31 @@
+// Copyright 2021 Gin Core Team.  All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.17
+// +build !go1.17
+
+package gin
+
+import (
+	"bytes"
+	"mime/multipart"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestContextFormFileFailed16(t *testing.T) {
+	buf := new(bytes.Buffer)
+	mw := multipart.NewWriter(buf)
+	mw.Close()
+	c, _ := CreateTestContext(httptest.NewRecorder())
+	c.Request, _ = http.NewRequest("POST", "/", nil)
+	c.Request.Header.Set("Content-Type", mw.FormDataContentType())
+	c.engine.MaxMultipartMemory = 8 << 20
+	f, err := c.FormFile("file")
+	assert.Error(t, err)
+	assert.Nil(t, f)
+}
diff --git a/context_1.17_test.go b/context_1.17_test.go
new file mode 100644
index 0000000..431d54c
--- /dev/null
+++ b/context_1.17_test.go
@@ -0,0 +1,33 @@
+// Copyright 2021 Gin Core Team.  All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+//go:build go1.17
+// +build go1.17
+
+package gin
+
+import (
+	"bytes"
+	"mime/multipart"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestContextFormFileFailed17(t *testing.T) {
+	buf := new(bytes.Buffer)
+	mw := multipart.NewWriter(buf)
+	mw.Close()
+	c, _ := CreateTestContext(httptest.NewRecorder())
+	c.Request, _ = http.NewRequest("POST", "/", nil)
+	c.Request.Header.Set("Content-Type", mw.FormDataContentType())
+	c.engine.MaxMultipartMemory = 8 << 20
+	assert.Panics(t, func() {
+		f, err := c.FormFile("file")
+		assert.Error(t, err)
+		assert.Nil(t, f)
+	})
+}
diff --git a/context_test.go b/context_test.go
index 176eaae..f9792e3 100644
--- a/context_test.go
+++ b/context_test.go
@@ -87,19 +87,6 @@ func TestContextFormFile(t *testing.T) {
 	assert.NoError(t, c.SaveUploadedFile(f, "test"))
 }
 
-func TestContextFormFileFailed(t *testing.T) {
-	buf := new(bytes.Buffer)
-	mw := multipart.NewWriter(buf)
-	mw.Close()
-	c, _ := CreateTestContext(httptest.NewRecorder())
-	c.Request, _ = http.NewRequest("POST", "/", nil)
-	c.Request.Header.Set("Content-Type", mw.FormDataContentType())
-	c.engine.MaxMultipartMemory = 8 << 20
-	f, err := c.FormFile("file")
-	assert.Error(t, err)
-	assert.Nil(t, f)
-}
-
 func TestContextMultipartForm(t *testing.T) {
 	buf := new(bytes.Buffer)
 	mw := multipart.NewWriter(buf)
@@ -2150,3 +2137,14 @@ func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
 		})
 	}
 }
+
+func TestContextAddParam(t *testing.T) {
+	c := &Context{}
+	id := "id"
+	value := "1"
+	c.AddParam(id, value)
+
+	v, ok := c.Params.Get(id)
+	assert.Equal(t, ok, true)
+	assert.Equal(t, value, v)
+}