使用 Echo 测试 POST 请求(预期输出与实际输出)
Testing POST request with Echo (expected vs actual output)
我是 Go 的新手,所以,如果这是一个愚蠢的问题,我很抱歉。
我最近一直在尝试使用 Echo API。我正在尝试测试 Go echo 的 route(POST) 处理程序,它获取 json 并将其放入数组中。下面是处理程序 main.go 和测试 test_main.go
的代码
main.go
type Houses struct {
Name string `json:"name,ommitempty"`
Address string `json:"address,omitempty"`
}
var houses []Houses
func newHouse(c echo.Context) error {
m := echo.Map{}
if err := c.Bind(&m); err != nil {
return err
}
dv := Houses{
Name: m["name"].(string),
Address: m["address"].(string),
}
houses = append(houses, dv)
js, _ := json.Marshal(houses)
fmt.Println(fmt.Sprintf("%s", js))
return c.JSON(http.StatusOK, string(js))
}
test_main.go
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/labstack/echo"
"github.com/stretchr/testify/assert"
)
var userJSON = `{"name":"Jhon Doe","address":"High St."}`
func TestModel(t *testing.T) {
url := "/new_house"
e := echo.New()
req, err := http.NewRequest(http.MethodPost, url, strings.NewReader(userJSON))
req.Header.Set("Content-Type", "application/json")
if err != nil {
t.Errorf("The request could not be created because of: %v", err)
}
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
// c.SetPath("/new_house")
// c.JSON(http.StatusOK, Devices{"Jhon Doe", "Middle Way"})
res := rec.Result()
defer res.Body.Close()
if assert.NoError(t, newHouse(c)) {
assert.Equal(t, http.StatusOK, rec.Code)
assert.Equal(t, "["+userJSON+"]", rec.Body.String())
}
}
即使通过 curl 调用处理程序正常工作,测试也会失败并显示如下错误。
[{"name":"Jhon Doe","address":"High St."}]
--- FAIL: TestModel (0.00s)
/home/gaidaros/Code/echo-badger/models/model_test.go:34:
Error Trace: model_test.go:34
Error: Not equal:
expected: "[{\"name\":\"Jhon Doe\",\"address\":\"High St.\"}]"
actual : "\"[{\\"name\\":\\"Jhon Doe\\",\\"address\\":\\"High St.\\"}]\""
Diff:
--- Expected
+++ Actual
@@ -1 +1 @@
-[{"name":"Jhon Doe","address":"High St."}]
+"[{\"name\":\"Jhon Doe\",\"address\":\"High St.\"}]"
Test: TestModel
FAIL
exit status 1
经过几天的努力,我无法弄清楚如何使实际输出符合预期,所以我在这里发帖希望能克服这个障碍。感谢您的帮助!
您在 []Houses
上调用 json.Marshal
,它将其编组为 JSON 字符串,然后您使用 JSON 字符串调用 echo.Context.JSON
,内部调用 json.Marshal
。双重编组导致转义。参见示例。 (为简洁起见省略了错误检查)
https://play.golang.org/p/nYvHS4huy0M
h := &Houses{"Jhon Doe", "High St."}
d, _ := json.Marshal(h)
// double marshal bad
d, _ = json.Marshal(string(d))
fmt.Println(string(d))
// prints "{\"name\":\"Jhon Doe\",\"address\":\"High St.\"}"
您的解决方案是将切片传递给您的 c.JSON
调用。作为旁注,您应该能够将结构传递给 c.Bind
而不是使用带有类型断言的映射。
我是 Go 的新手,所以,如果这是一个愚蠢的问题,我很抱歉。
我最近一直在尝试使用 Echo API。我正在尝试测试 Go echo 的 route(POST) 处理程序,它获取 json 并将其放入数组中。下面是处理程序 main.go 和测试 test_main.go
的代码main.go
type Houses struct {
Name string `json:"name,ommitempty"`
Address string `json:"address,omitempty"`
}
var houses []Houses
func newHouse(c echo.Context) error {
m := echo.Map{}
if err := c.Bind(&m); err != nil {
return err
}
dv := Houses{
Name: m["name"].(string),
Address: m["address"].(string),
}
houses = append(houses, dv)
js, _ := json.Marshal(houses)
fmt.Println(fmt.Sprintf("%s", js))
return c.JSON(http.StatusOK, string(js))
}
test_main.go
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/labstack/echo"
"github.com/stretchr/testify/assert"
)
var userJSON = `{"name":"Jhon Doe","address":"High St."}`
func TestModel(t *testing.T) {
url := "/new_house"
e := echo.New()
req, err := http.NewRequest(http.MethodPost, url, strings.NewReader(userJSON))
req.Header.Set("Content-Type", "application/json")
if err != nil {
t.Errorf("The request could not be created because of: %v", err)
}
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
// c.SetPath("/new_house")
// c.JSON(http.StatusOK, Devices{"Jhon Doe", "Middle Way"})
res := rec.Result()
defer res.Body.Close()
if assert.NoError(t, newHouse(c)) {
assert.Equal(t, http.StatusOK, rec.Code)
assert.Equal(t, "["+userJSON+"]", rec.Body.String())
}
}
即使通过 curl 调用处理程序正常工作,测试也会失败并显示如下错误。
[{"name":"Jhon Doe","address":"High St."}]
--- FAIL: TestModel (0.00s)
/home/gaidaros/Code/echo-badger/models/model_test.go:34:
Error Trace: model_test.go:34
Error: Not equal:
expected: "[{\"name\":\"Jhon Doe\",\"address\":\"High St.\"}]"
actual : "\"[{\\"name\\":\\"Jhon Doe\\",\\"address\\":\\"High St.\\"}]\""
Diff:
--- Expected
+++ Actual
@@ -1 +1 @@
-[{"name":"Jhon Doe","address":"High St."}]
+"[{\"name\":\"Jhon Doe\",\"address\":\"High St.\"}]"
Test: TestModel
FAIL
exit status 1
经过几天的努力,我无法弄清楚如何使实际输出符合预期,所以我在这里发帖希望能克服这个障碍。感谢您的帮助!
您在 []Houses
上调用 json.Marshal
,它将其编组为 JSON 字符串,然后您使用 JSON 字符串调用 echo.Context.JSON
,内部调用 json.Marshal
。双重编组导致转义。参见示例。 (为简洁起见省略了错误检查)
https://play.golang.org/p/nYvHS4huy0M
h := &Houses{"Jhon Doe", "High St."}
d, _ := json.Marshal(h)
// double marshal bad
d, _ = json.Marshal(string(d))
fmt.Println(string(d))
// prints "{\"name\":\"Jhon Doe\",\"address\":\"High St.\"}"
您的解决方案是将切片传递给您的 c.JSON
调用。作为旁注,您应该能够将结构传递给 c.Bind
而不是使用带有类型断言的映射。