【问题标题】:Testing POST request with Echo (expected vs actual output)使用 Echo 测试 POST 请求(预期与实际输出)
【发布时间】:2018-11-05 23:00:20
【问题描述】:

我是 Go 的新手,所以,如果这是一个愚蠢的问题,请见谅。

我最近一直在尝试使用 Echo 的一些 API。我正在尝试测试获取 json 并将其放入数组的 Go echo 的 route(POST) 处理程序。下面是处理程序 ma​​in.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

经过几天的努力,我无法弄清楚如何使实际输出与预期相匹配,所以我在这里发帖希望能克服这个障碍。任何帮助表示赞赏!

【问题讨论】:

    标签: json go post go-echo


    【解决方案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,而不是使用带有类型断言的映射。

    【讨论】:

    • 我不敢相信它这么简单。我现在觉得很傻。我一定会记住你的观点。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 2019-12-20
    • 2020-03-26
    相关资源
    最近更新 更多