简单错误单元测试的Golang问题

3df52oht  于 2023-03-16  发布在  Go
关注(0)|答案(1)|浏览(83)

我在尝试测试这个函数时遇到了麻烦,里面有一个错误。下面是我的ResponseJson函数,它不返回错误,但发送一个响应json。

func ResponseJson(w http.ResponseWriter, Code int, Message string) {
    jsonStatus := struct {
        Code int `json:"code"`
        Message string `json:"message"`
    }{
        Message: Message,
        Code: Code,
    }

    bs, err := json.Marshal(jsonStatus);

    if err != nil {
        log.Println("Error in Marshal JSON in ResponseJson: ", err)
        str := "Internal Server Error. Please contact the System Administrator."
        io.WriteString(w, str);
        return 
    } else {
        io.WriteString(w, string(bs));
        return
    }
    
}

下面是我的单元测试代码,它创建了一个模拟的ResponseWriter,并且能够成功地测试编写器响应json的情况,没有错误。由于我没有在ResponseJson()函数中返回错误类型,我如何在Test_ResponseJson函数中测试它,如下所示?

func Test_ResponseJson(t *testing.T) {
    responseJsonTests := []struct {
        testName string
        code int
        message string
        expectedJsonResponse string
    } {
        {"Successful Login", http.StatusOK, "Successfully Logged In!", `{"code":200,"message":"Successfully Logged In!"}`},
        {"Existing username", http.StatusBadRequest, "Username already exists. Please try again.", `{"code":400,"message":"Username already exists. Please try again."}`},
    }

    for _, e := range responseJsonTests {
        // Creating a mock ResponseWriter
        w := httptest.NewRecorder()

        ResponseJson(w, e.code, e.message)

        // Read the response body as a string
        body, _ := io.ReadAll(w.Result().Body)
        actual := string(body)

        expected := e.expectedJsonResponse
        if actual != expected {
            t.Errorf("%s: expected %s but got %s", e.testName, e.expectedJsonResponse, actual)
        }
    }
}

此外,我还创建了一个函数,为log.Println()内置函数生成实际的日志输出。我知道log.Println()函数是一个内置函数,它不太可能失败。但是,我希望在我的单元测试中实现100%的覆盖率。请帮助!谢谢:)

func GenerateLogOutput(message string, errorMessage string) string {
    // Create a new bytes.Buffer to capture the log output
    var buf bytes.Buffer

    // Redirect log output to a different destination set as a buffer
    // By default, log message are written to the standard error stream os.Stderr
    log.SetOutput(&buf)

    // Generate an error
    err := errors.New(errorMessage)

    w := httptest.NewRecorder()

    // Calling the function
    InternalServerError(w, message, err)
    actualOutput := buf.String()

    return actualOutput
}
tcomlyy6

tcomlyy61#

简单地说,我们可以为ResponseJson函数编写一个测试用例,如下所示。

func Test_ResponseJson(t *testing.T) {
    tests := []struct {
        Code        int
        Message     string
        ExpectedStr string
    }{
        {
            Code:        1,
            Message:     "sample message",
            ExpectedStr: "{\"code\":1,\"message\":\"sample message\"}",
        },
    }
    for _, test := range tests {
        w := httptest.NewRecorder()

        ResponseJson(w, test.Code, test.Message)

        res := w.Result()
        data, err := ioutil.ReadAll(res.Body)
        res.Body.Close()

        actualStr := string(data)

        assert.Nil(t, err, "Invalid test data")
        assert.Equal(t, actualStr, test.ExpectedStr)
    }
}

无法从bs, err := json.Marshal(jsonStatus)获取错误。json.Marshal函数可返回两种类型的错误。

  1. UnsupportedTypeError(例如:通道、复数和函数值)
  2. UnsupportedValueError(例如:循环数据结构)
    我们无法分析值以生成上述错误之一。我们正在分析具有受支持的值和受支持的类型的结构。因此,我们无法编写100%覆盖率的测试。

相关问题