I know this is an old question, but it still appeared in the search results, so I decided to give a possible answer.
You can isolate code from helper functions that return a โbreakโ function for cleaning after yourself. Here is one possible way to start the server and close it at the end of the test.
func setUpServer() (string, func()) { h := func(w http.ResponseWriter, r *http.Request) { code := http.StatusTeapot http.Error(w, http.StatusText(code), code) } ts := httptest.NewServer(http.HandlerFunc(h)) return ts.URL, ts.Close } func TestWithServer(t *testing.T) { u, close := setUpServer() defer close() rsp, err := http.Get(u) assert.Nil(t, err) assert.Equal(t, http.StatusTeapot, rsp.StatusCode) }
This starts the server with net/http/httptest and returns its URL along with a function that acts as a "break". This function is added to the deferral stack, so it is always called regardless of the exit from the test case.
Optionally, you can pass *testing.T if you have a more complicated setup there and you need to handle errors. This example shows the set function that returns *url.URL instead of a string in URL format, and the analysis may possibly return an error.
func setUpServer(t *testing.T) (*url.URL, func()) { h := func(w http.ResponseWriter, r *http.Request) { code := http.StatusTeapot http.Error(w, http.StatusText(code), code) } ts := httptest.NewServer(http.HandlerFunc(h)) u, err := url.Parse(ts.URL) assert.Nil(t, err) return u, ts.Close } func TestWithServer(t *testing.T) { u, close := setUpServer(t) defer close() u.Path = "/a/b/c/d" rsp, err := http.Get(u.String()) assert.Nil(t, err) assert.Equal(t, http.StatusTeapot, rsp.StatusCode) }