2017-06-26 5 views
0

Ich schrieb eine kleine Testfunktion in go. Ich habe es schwer, eine Anfrage an den tatsächlichen Endpunkt zu stellen und sie zu testen. Ich habe versucht, die Datei zu importieren, die die Handler-Funktion hat (ich glaube, ich versuche, ganzes Verzeichnis zu importieren: import (".")). Sowohl meine project.go und handler_test.go sind im selben Verzeichnis (ich glaube nicht, dass das wichtig ist). Könnte mir jemand den Kopf geben, damit ich mehr Tests schreiben kann? Hier ist meine project.go:Wie testen Sie einen Endpunkt in go?

package main 

import (
    "encoding/json" 
    "net/http" 

    "github.com/gorilla/mux" 
    "github.com/rs/cors" 

) 

type Person struct { 
    ID  string `json:"id,omitempty"` 
    Firstname string `json:"firstname,omitempty"` 
    Lastname string `json:"lastname,omitempty"` 
    Address *Address `json:"address,omitempty"` 
} 

type Address struct { 
    City string `json:"city,omitempty"` 
    State string `json:"state,omitempty"` 
} 

var people []Person; 

func GetPersonEndpoint(w http.ResponseWriter, req *http.Request) { 
    params := mux.Vars(req) 
    for _, item := range people { 
     if item.ID == params["id"] { 
      json.NewEncoder(w).Encode(item) 
      return 
     } 
    } 
    json.NewEncoder(w).Encode(&Person{}) 
} 


func GetPeopleEndpoint(w http.ResponseWriter, req *http.Request) { 
json.NewEncoder(w).Encode(people) 
} 

func CreatePersonEndpoint(w http.ResponseWriter, req *http.Request) { 
    params := mux.Vars(req) 
    var person Person 
    _ = json.NewDecoder(req.Body).Decode(&person) 
    person.ID = params["id"] 
    people = append(people, person) 
    json.NewEncoder(w).Encode(people) 
} 

func DeletePersonEndpoint(w http.ResponseWriter, req *http.Request) { 
    params := mux.Vars(req) 
    for index, item := range people { 
     if item.ID == params["id"] { 
      people = append(people[:index], people[index+1:]...) 
      break 
     } 
    } 
    json.NewEncoder(w).Encode(people) 
} 

func main() { 
    Router := mux.NewRouter() 
    people = append(people, Person{ID: "1", Firstname: "sarath", Lastname: "v", Address: &Address{City: "sunnyvale", State: "CA"}}) 
    people = append(people, Person{ID: "2", Firstname: "dead", Lastname: "pool"}) 

    // router.PathPrefix("/tmpfiles/").Handler(http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir(".")))) 

    Router.HandleFunc("/people", GetPeopleEndpoint).Methods("GET") 
    Router.HandleFunc("/people/{id}", GetPersonEndpoint).Methods("GET") 
    Router.HandleFunc("/people/{id}", CreatePersonEndpoint).Methods("POST") 

    c := cors.New(cors.Options{ 
    AllowedOrigins: []string{"http://localhost:3000"}, 
    AllowCredentials: true, 
}) 

// Insert the middleware 
    handler := c.Handler(Router) 
    http.ListenAndServe(":12345", handler) 

} 

Hier ist mein handler_test.go. In diesem Code teste ich GetPersonEndPoint.

package main 

import (
    "." 
    "net/http" 
    "net/http/httptest" 
    "testing" 
    "encoding/json" 
) 

func checkResponseCode(t *testing.T, expected, actual int) { 
    if expected != actual { 
     t.Errorf("Expected response code %d. Got %d\n", expected, actual) 
    } 
} 

func executeRequest(req *http.Request) *httptest.ResponseRecorder { 
    rr := httptest.NewRecorder() 
    handler := http.HandlerFunc(GetPersonEndpoint) 
    handler.ServeHTTP(rr, req) 
    if status := rr.Code; status != http.StatusOK { 
     fmt.Printf("Handler returned wrong status code: got %v want %v" , status, http.statusOk); 
     } 
    return rr 
} 

func TestGetPersonEndPoint(t *testing.T){ 
    req, _ := http.NewRequest("GET", "/people/5", nil) 
    response := executeRequest(req) 
    checkResponseCode(t, http.StatusNotFound, response.Code) 
    var m map[string]string 
    json.Unmarshal(response.Body.Bytes(), &m) 
    if m["error"] != "Product not found" { 
     t.Errorf("Expected the 'error' key of the response to be set to 'Product not found'. Got '%s'", m["error"]) 
    } 
} 

Und schließlich ist dies der Fehler:

./new.go:14: main redeclared in this block 
    previous declaration at ./myproject.go:62 
./new.go:20: not enough arguments in call to server.ListenAndServeTLS 
    have() 
    want (string, string) 
+0

aus. Sie importieren Ihren Code nicht, um zu testen, die Tests existieren in demselben Paket. Wenn Sie ein Paket für Black-Box-Tests importieren müssen, verwenden Sie immer den vollständigen Importpfad, niemals den relativen Pfad (Sie können jedoch niemals ein Hauptpaket importieren). – JimB

+2

Der Fehler sagt alles: Sie haben zwei Funktionen, die beide 'Main' im selben Paket, eine in' new.go' Zeile 14, eine in 'myproject.go' Zeile 62. Sie können nicht zwei Funktionen der gleicher Name im selben Paket (außer für den Spezialfall der 'init'-Funktionen). Sie haben auch einen ungültigen Aufruf von 'ListenAndServeTLS', der keine Argumente übergibt, wenn diese Funktion zwei Argumente benötigt, beide Zeichenfolgen. – Adrian

+0

@Adrian Ich beobachtete keine anderen Dateien. Ich habe ein flaches Verzeichnis, das das Problem verursacht hat. Es gibt eine Datei new.go in meinem Verzeichnis, das die zweite main() hat. Ich habe es korrigiert. Wie importiere ich den spezifischen Handler (ich mache es so: Import ("Projekt"))? –

Antwort

1

Werfen Sie einen Blick auf einige http Tests, die ich geschrieben habe: https://github.com/eamonnmcevoy/go_web_server/blob/master/pkg/server/user_router_test.go

// Arrange 
    us := mock.UserService{} 
    testUserRouter := NewUserRouter(&us, mux.NewRouter()) 
... 
    w := httptest.NewRecorder() 
    r, _ := http.NewRequest("PUT", "/", payload) 
    r.Header.Set("Content-Type", "application/json") 
    testUserRouter.ServeHTTP(w, r) 

einfach eine Instanz des Routers und Anruf erstellen die Endpunkte mit go's httptest. Dieses Snippet führt eine PUT Anfrage an dem Standardendpunkt /

+0

Wie installiere ich das Paket go_rest_api/pkg? –

+0

@SarathVelamuri Sie nicht, das ist nur der Name meines Projekts. Sie müssen nur eine Instanz der Struktur erstellen, die Ihre Routen enthält, und sie mit 'httptest' und einer Anfrage bedienen. In meinem Fall ist "testUserRouter" eine (schlecht named?) Instanz meiner 'UserRouter' Struktur, ich rufe eine' PUT' Anfrage auf dem Pfad '"/"' –

+1

auf Ja. Das habe ich gesehen. Ich habe es getan und es hat funktioniert. –

Verwandte Themen