REST API的Golang测试转储了整个数据库

时间:2019-04-18 17:23:18

标签: rest unit-testing go

我写了一个小型的Web服务来学习单元测试。有一个端点可以使用三个字母的字符串来获取数据。我的代码运行良好。正确的查询是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

我看过很多教程,例如this,我觉得很清楚。据我所知,我的测试代码是正确的。在进行测试之前,我还尝试过运行main.go。但这没关系,对吧?

我想念什么?

0 个答案:

没有答案