Я написал небольшой веб-сервис для изучения модульного тестирования.Существует одна конечная точка для получения данных с трехбуквенной строкой.Мой код работает нормально.Правильный запрос - http://localhost:8000/iata/thu
, последний бит thu
- трехбуквенная строка.Я могу получить правильные данные с ним.Я также могу успешно получить 404 с неправильными.Затем я написал тест.Сбой и сброс всей базы данных.
База данных SQLite3, main.go и main_test.go находятся в одном каталоге.
Вот main_test.go:
package main
import (
"net/http"
"net/http/httptest"
"testing"
)
func TestIata(t *testing.T) {
// "thu" is the three-letter code.
// I also tried "http://localhost:8000/iata/thu"
req, err := http.NewRequest("GET", "/iata/thu", nil)
if err != nil {
t.Fatal(err)
}
rr := httptest.NewRecorder()
handler := http.HandlerFunc(iata)
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 := `[{"airport_id":"10","name":"Thule Air Base","city":"Thule","country":"Greenland","iata":"THU","icao":"BGTL","latitude":"76.5311965942","longitude":"-68.7032012939","altitude":"251","timezone":"-4","dst":"E","tz_db":"America/Thule","type":"airport","source":"OurAirports"}]`
if rr.Body.String() != expected {
t.Errorf("handler returned unexpected body: got %v want %v",
rr.Body.String(), expected)
}
}
Вот main.go:
package main
import (
"database/sql"
"encoding/json"
"log"
"net/http"
"github.com/gorilla/mux"
_ "github.com/mattn/go-sqlite3"
)
type datum struct {
AirportID string `json:"airport_id,omitempty"`
...
}
func check(err error) {
...
}
// Accesses the database and gets relevant rows.
func getRows(column string, searchTerm string) *sql.Rows {
db, err := sql.Open("sqlite3", "airports.db")
check(err)
stmt := `SELECT * FROM airports WHERE ` + column + ` LIKE ? COLLATE NOCASE;`
rows, err := db.Query(stmt, `%`+searchTerm+`%`)
check(err)
return rows
}
// Processes the data into a slice so it can be sent out as JSON.
func processData(rows *sql.Rows) []datum {
data := []datum{}
// For each row, insert data into a datum instance and then append to data slice.
for rows.Next() {
datum := datum{}
rows.Scan(&datum.AirportID,
...)
data = append(data, datum)
}
rows.Close()
return data
}
// Uses the above code to get data from the database, process it, and send it.
func getAndSendData(w http.ResponseWriter, r *http.Request, searchType string) {
params := mux.Vars(r)
searchTerm := params[searchType]
datum := getRows(searchType, searchTerm)
processed := processData(datum)
if len(processed) == 0 {
http.Error(w, "Data not found.", 404)
return
}
json.NewEncoder(w).Encode(processed)
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/iata/{iata}", iata).Methods("GET")
log.Fatal(http.ListenAndServe(":8000", router))
}
func iata(w http.ResponseWriter, r *http.Request) {
searchType := "iata"
getAndSendData(w, r, searchType)
}
При выполнении теста в результате будет выгружена вся база данных:
=== RUN TestIata
--- FAIL: TestIata (0.21s)
main_test.go:46: handler returned unexpected body: got [ENTIRE DATABASE DUMPED HERE] want [CORRECT DATA HERE]
FAIL
exit status 1
Я просмотрел множество учебных пособий, таких как этот тот, который я чувствую, довольно ясно.Насколько я могу судить, мой тестовый код правильный.Я также попытался запустить main.go перед выполнением теста.Но это не должно иметь значения, верно?
Чего мне не хватает?