Golang测试用例无法匹配预期结果怎么办

Golang测试用例无法匹配预期结果怎么办 我正在使用 gorilla mux 包,我希望能够展示完整的测试用例,但遗憾的是,由于预期结果是一个返回的大型 JSON,测试用例的代码行数太多,甚至无法在这里完整展示。

我知道我的预期结果应该与实际结果相等,但似乎运行单元测试时并不奏效。

func TestHealthCheckHandler(t *testing.T) {
    req, err := http.NewRequest("GET", "/health", nil)

    if err != nil {

        t.Fatal(err)

    }

    rr := httptest.NewRecorder()
    handler := http.HandlerFunc(HealthCheckHandler)
    handler.ServeHTTP(rr, req)

    if status := rr.Code; status != http.StatusOK {
        t.Errorf("handler returned wrong status code: got %v want %v",
            status, http.StatusOK)
    }

    expected := `{"alive": true}`
    if rr.Body.String() != expected {
        t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected)
    }

}

由于我的代码太长而无法展示,这里给出了它应有的格式示例。理想情况下,即使我知道它们是相等的,我也无法让我的预期结果等于 rr.Body.String()。我认为这可能与空白字符有关……我该如何解决这个问题?


更多关于Golang测试用例无法匹配预期结果怎么办的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

你好,

在这种情况下,我首先会做的是将 rr.Body.String()expected 的内容写入两个文件,然后用差异比较工具(或者可能只是手动并排查看,因为差异可能很明显)进行比较。

或者,如果空格是唯一的问题,可以考虑在比较字符串之前,通过修剪空格并对 rr.Body.String()expected 应用相同的缩进来“规范化”JSON。(例如,参见 json.Compactjson.Indent。)

更多关于Golang测试用例无法匹配预期结果怎么办的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题很可能出在JSON格式的空白字符或字段顺序上。使用encoding/json包进行规范化比较可以解决这个问题:

func TestHealthCheckHandler(t *testing.T) {
    req, err := http.NewRequest("GET", "/health", nil)
    if err != nil {
        t.Fatal(err)
    }

    rr := httptest.NewRecorder()
    handler := http.HandlerFunc(HealthCheckHandler)
    handler.ServeHTTP(rr, req)

    if status := rr.Code; status != http.StatusOK {
        t.Errorf("handler returned wrong status code: got %v want %v",
            status, http.StatusOK)
    }

    // 解析实际响应
    var actual map[string]interface{}
    if err := json.Unmarshal(rr.Body.Bytes(), &actual); err != nil {
        t.Fatalf("failed to unmarshal actual response: %v", err)
    }

    // 解析预期响应
    expectedJSON := `{"alive": true}`
    var expected map[string]interface{}
    if err := json.Unmarshal([]byte(expectedJSON), &expected); err != nil {
        t.Fatalf("failed to unmarshal expected response: %v", err)
    }

    // 比较两个解析后的JSON对象
    if !reflect.DeepEqual(actual, expected) {
        t.Errorf("handler returned unexpected body: got %v want %v", actual, expected)
    }
}

如果只需要比较特定字段,可以更精确地比较:

func TestHealthCheckHandler(t *testing.T) {
    // ... 前面的代码相同 ...

    // 只比较alive字段
    var response struct {
        Alive bool `json:"alive"`
    }
    
    if err := json.Unmarshal(rr.Body.Bytes(), &response); err != nil {
        t.Fatalf("failed to unmarshal response: %v", err)
    }

    if !response.Alive {
        t.Errorf("expected alive to be true, got %v", response.Alive)
    }
}

对于大型JSON,可以使用JSON字符串规范化:

func normalizeJSON(jsonStr string) (string, error) {
    var data interface{}
    if err := json.Unmarshal([]byte(jsonStr), &data); err != nil {
        return "", err
    }
    normalized, err := json.Marshal(data)
    if err != nil {
        return "", err
    }
    return string(normalized), nil
}

// 在测试中使用
actualNormalized, _ := normalizeJSON(rr.Body.String())
expectedNormalized, _ := normalizeJSON(expectedJSON)
if actualNormalized != expectedNormalized {
    t.Errorf("handler returned unexpected body")
}
回到顶部