Reputation: 2032
I've googled all over for this but can't find anything.
I have a struct that takes in a http.Client
and it sends several GET requests. In my tests I want to mock the responses so it's not sending real requests.
Currently I've figured out how to only serve 1 request, like this:
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
file, err := os.Open("./testdata/1.html")
if err != nil {
t.Error(err)
}
bytes, err := ioutil.ReadAll(file)
if err != nil {
t.Error(err)
}
w.Write(bytes)
}))
ts.Client() // Now I can inject this client into my struct.
So once that response is mocked out and the http client is performs a new request, my tests are sending out real requests after that.
How do I allow for several handlers so I can mock several responses upon calling http.Client.Get(...)
?
Upvotes: 11
Views: 8457
Reputation: 353
Since the original question uses httptest.NewServer - you can register a ServeMux on the httptest.Server function, and then you can add several routes to that mux:
mux := http.NewServeMux()
mux.HandleFunc("/someroute/", func(res http.ResponseWriter, req *http.Request) {
...do some stuff...
})
mux.HandleFunc("/someotherroute/", func(res http.ResponseWriter, req *http.Request) {
...do other stuff...
})
ts := httptest.NewServer(mux)
defer ts.Close()
Upvotes: 15
Reputation: 2564
ServeMux.Handle can be used to setup a server to handle multiple requests like in this example.
package main
import (
"log"
"net/http"
)
const addr = "localhost:12345"
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/hello", HandleHello)
// other handlers can be assigned to separate paths
log.Printf("Now listening on %s...\n", addr)
server := http.Server{Handler: mux, Addr: addr}
log.Fatal(server.ListenAndServe())
}
func HandleHello(w http.ResponseWriter, r *http.Request) {
log.Printf("Hello!")
}
But to be honest you probably just want to abstract the http.Client
behind an interface that you've created, and then stub that with a test implementation that returns exactly what you want. By doing this you avoid the overhead of http communication in your tests.
Upvotes: 5