Тестирование HTTP-маршрутов в Golang

Я использую мультиплексор Gorilla и пакет net/http для создания некоторых маршрутов следующим образом.

package routes

//some imports

//some stuff

func AddQuestionRoutes(r *mux.Router) {
    s := r.PathPrefix("/questions").Subrouter()
    s.HandleFunc("/{question_id}/{question_type}", getQuestion).Methods("GET")
    s.HandleFunc("/", postQuestion).Methods("POST")
    s.HandleFunc("/", putQuestion).Methods("PUT")
    s.HandleFunc("/{question_id}", deleteQuestion).Methods("DELETE")
}

Я пытаюсь написать тест для проверки этих маршрутов. Например, я пытаюсь протестировать маршрут GET, специально пытаясь вернуть 400, поэтому у меня есть следующий тестовый код.

package routes

//some imports

var m *mux.Router
var req *http.Request
var err error
var respRec *httptest.ResponseRecorder

func init() {
    //mux router with added question routes
    m = mux.NewRouter()
    AddQuestionRoutes(m)

    //The response recorder used to record HTTP responses
    respRec = httptest.NewRecorder()
}

func TestGet400(t *testing.T) {
    //Testing get of non existent question type
    req, err = http.NewRequest("GET", "/questions/1/SC", nil)
    if err != nil {
        t.Fatal("Creating 'GET /questions/1/SC' request failed!")
    }

    m.ServeHTTP(respRec, req)

    if respRec.Code != http.StatusBadRequest {
        t.Fatal("Server error: Returned ", respRec.Code, " instead of ", http.StatusBadRequest)
    }
}

Однако, когда я запускаю этот тест, я получаю 404, предположительно, потому что запрос не маршрутизируется правильно.?

Когда я тестирую этот GET-маршрут из браузера, он возвращает 400, поэтому я уверен, что есть проблема с настройкой теста.


person moesef    schedule 16.08.2014    source источник
comment
Трудно сказать, не видя кода getQuestion. Я воссоздал вашу настройку и реализовал getQuestion как неактивную. Когда я запускаю go test ./..., я получаю следующую ошибку: routes_test.go:32: Server error: Returned 200 instead of 400.   -  person Amit Kumar Gupta    schedule 16.08.2014
comment
догадаться. На самом деле я проводил другой тест, но использовал тот же respRec вместо того, чтобы создавать новый рекордер с httptest.NewRecorder(). Я предполагаю, что есть некоторые ограничения на повторное использование одного и того же httpRecorder.   -  person moesef    schedule 16.08.2014


Ответы (1)


Использование init() здесь подозрительно. Он выполняется только один раз как часть инициализации программы. Вместо этого, возможно, что-то вроде:

func setup() {
    //mux router with added question routes
    m = mux.NewRouter()
    AddQuestionRoutes(m)

    //The response recorder used to record HTTP responses
    respRec = httptest.NewRecorder()
}

func TestGet400(t *testing.T) {
    setup()
    //Testing get of non existent question type
    req, err = http.NewRequest("GET", "/questions/1/SC", nil)
    if err != nil {
        t.Fatal("Creating 'GET /questions/1/SC' request failed!")
    }

    m.ServeHTTP(respRec, req)

    if respRec.Code != http.StatusBadRequest {
        t.Fatal("Server error: Returned ", respRec.Code, " instead of ", http.StatusBadRequest)
    }
}

где вы вызываете setup() в начале каждого соответствующего теста. Ваш исходный код использовал один и тот же respRec с другими тестами, что, вероятно, искажало результаты ваших тестов.

Если вам нужна среда тестирования, предоставляющая дополнительные функции, такие как приспособления для установки/демонтажа, см. такие пакеты, как gocheck.

person dyoo    schedule 30.08.2014
comment
Не могли бы вы показать AddQuestionRoutes(), можем ли мы добавить только определенные тестовые маршруты? - person Abhijeet Padwal; 10.04.2020
comment
извините, понял, дело в самом вопросе - person Abhijeet Padwal; 11.04.2020