gpt4 book ai didi

unit-testing - 进行单元测试-样板

转载 作者:行者123 更新时间:2023-12-01 22:10:36 26 4
gpt4 key购买 nike

这是我的Todo应用程序的基本结构,看起来像是“main.go”;

package main

import (
"encoding/json"
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
)

// Todo Struct (Model)
type Todo struct {
Id string `json:"id"`
Task string `json:"task"`
Completed bool `json:"completed"`
}

var todos []Todo

// Get All Todos
func GetTodos(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(todos)
}

func main() {
// Init Router
r := mux.NewRouter()

// Mock Data
todos = append(todos, Todo{Id: "1", Task: "FirstTask", Completed: false})
todos = append(todos, Todo{Id: "2", Task: "SecondTask", Completed: false})

fmt.Println("Go dude dude go ")

r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello dudes")
})

r.HandleFunc("/api/todos", GetTodos).Methods("GET")

log.Fatal(http.ListenAndServe(":8080", r))
}
这是我的“main_test.go”
package main

import (
"net/http"
"net/http/httptest"
"testing"
)

func TestGetTodos(t *testing.T) {
req, err := http.NewRequest("GET", "/api/todos", nil)
if err != nil {
t.Fatal(err)
}
rr := httptest.NewRecorder()
handler := http.HandlerFunc(GetTodos)
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)
}

// Check the response body is what we expect.
expected := `[{Id: "1", Task: "FirstTask", Completed: false},{Id: "2", Task: "SecondTask", Completed: false}]`
if rr.Body.String() != expected {
t.Errorf("handler returned unexpected body: got %v want %v",
rr.Body.String(), expected)
}
}
问题出在这里,我不断收到以下错误;
--- FAIL: TestGetTodos (0.00s)
main_test.go:25: handler returned unexpected body: got null
want [{Id: "1", Task: "FirstTask", Completed: false},{Id: "2", Task: "SecondTask", Completed: false}]
FAIL
exit status 1
FAIL ..filesPath/backend 0.213s
我肯定错过了这么简单,但无法弄清楚。

最佳答案

在运行测试运行时,永远不会调用main,因此todos为空。

var todos []Todo
这就是 rr.Body.String()返回null的原因
如果将模拟数据生成代码移动到正在测试的 GetTodos函数中
var todos []Todo

// Get All Todos
func GetTodos(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
var mockTodos []Todo
mockTodos = append(mockTodos, Todo{Id: "1", Task: "FirstTask", Completed: false})
mockTodos = append(mockTodos, Todo{Id: "2", Task: "SecondTask", Completed: false})
json.NewEncoder(w).Encode(mockTodos)
}
测试仍然会失败,但是主体将不再为null而是显示
=== RUN   TestGetTodos
TestGetTodos: main_test.go:25: handler returned unexpected body: got [{"id":"1","task":"FirstTask","completed":false},{"id":"2","task":"SecondTask","completed":false}]
want [{Id: "1", Task: "FirstTask", Completed: false},{Id: "2", Task: "SecondTask", Completed: false}]
--- FAIL: TestGetTodos (0.00s)
FAIL
那是因为您的期望不是正确的json格式。如果您更换
expected := `[{Id: "1", Task: "FirstTask", Completed: false},{Id: "2", Task: "SecondTask", Completed: false}]`
expected := "[{\"id\":\"1\",\"task\":\"FirstTask\",\"completed\":false},{\"id\":\"2\",\"task\":\"SecondTask\",\"completed\":false}]\n"
那将帮助您通过测试。
我在预期字符串的末尾添加了换行符 \n,因为 json.NewEncoder(w).Encode(todos)在输出中添加了换行符

理想情况下,您不想使用全局变量来存储状态。您将拥有另一个可以存储状态或为您检索状态的对象(可能是从DB)。在测试中,您将使用状态初始化该对象,然后检查函数是否以该状态作为输入正确执行。
以下是 下一步可以做什么的简单示例。 main.go
//  Todo Struct (Model)
type Todo struct {
Id string `json:"id"`
Task string `json:"task"`
Completed bool `json:"completed"`
}

type App struct {
todos []Todo
}

// Get All Todos
func (a *App) GetTodos(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(a.todos)
}

func main() {
// Init Router
r := mux.NewRouter()

// Mock Data
app := App{todos: []Todo{
{Id: "1", Task: "FirstTask", Completed: false},
{Id: "2", Task: "SecondTask", Completed: false},
}}

fmt.Println("Go dude dude go ")

r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello dudes")
})

r.HandleFunc("/api/todos", app.GetTodos).Methods("GET")

log.Fatal(http.ListenAndServe(":8080", r))
}
main_test.go
func TestGetTodos(t *testing.T) {
req, err := http.NewRequest("GET", "/api/todos", nil)
if err != nil {
t.Fatal(err)
}

// Mock Data
app := App{todos: []Todo{
{Id: "1", Task: "FirstTask", Completed: false},
{Id: "2", Task: "SecondTask", Completed: false},
}}

rr := httptest.NewRecorder()
handler := http.HandlerFunc(app.GetTodos)
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)
}

// Check the response body is what we expect.
expected := "[{\"id\":\"1\",\"task\":\"FirstTask\",\"completed\":false},{\"id\":\"2\",\"task\":\"SecondTask\",\"completed\":false}]\n"
str := rr.Body.String()
if diff := cmp.Diff(expected , str); diff != "" {
t.Errorf("%s: mismatch (-want +got):\n%s", "", diff)
}
if str != expected {
t.Errorf("handler returned unexpected body: got %v want %v",
rr.Body.String(), expected)
}
}

关于unit-testing - 进行单元测试-样板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63979318/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com