Golang тест REST API сбрасывает всю базу данных - PullRequest
0 голосов
/ 18 апреля 2019

Я написал небольшой веб-сервис для изучения модульного тестирования.Существует одна конечная точка для получения данных с трехбуквенной строкой.Мой код работает нормально.Правильный запрос - 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 перед выполнением теста.Но это не должно иметь значения, верно?

Чего мне не хватает?

...