title: Why is the response body empty when running a test of mux API?
body: <p>I am trying to build and test a very basic API in Go to learn more about the language after following their tutorial. The API and the four routes defined work in Postman and the browser, but when trying to write the test for any of the routes, the ResponseRecorder doesn't have a body, so I cannot verify it is correct.</p>
  <p>I followed the example <a href="https://github.com/gorilla/mux#testing-handlers" rel="nofollow noreferrer">here</a> and it works, but when I change it for my route, there is no response.</p>
  <p>Here is my <code>main.go</code> file.</p>
  <pre class="lang-golang prettyprint-override"><code>package main
  
  import (
      &quot;encoding/json&quot;
      &quot;fmt&quot;
      &quot;log&quot;
      &quot;net/http&quot;
  
      &quot;github.com/gorilla/mux&quot;
  )
  
  // A Person represents a user.
  type Person struct {
      ID        string    `json:&quot;id,omitempty&quot;`
      Firstname string    `json:&quot;firstname,omitempty&quot;`
      Lastname  string    `json:&quot;lastname,omitempty&quot;`
      Location  *Location `json:&quot;location,omitempty&quot;`
  }
  
  // A Location represents a Person's location.
  type Location struct {
      City    string `json:&quot;city,omitempty&quot;`
      Country string `json:&quot;country,omitempty&quot;`
  }
  
  var people []Person
  
  // GetPersonEndpoint returns an individual from the database.
  func GetPersonEndpoint(w http.ResponseWriter, req *http.Request) {
      w.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
      params := mux.Vars(req)
      for _, item := range people {
          if item.ID == params[&quot;id&quot;] {
              json.NewEncoder(w).Encode(item)
              return
          }
      }
      json.NewEncoder(w).Encode(&amp;Person{})
  }
  
  // GetPeopleEndpoint returns all people from the database.
  func GetPeopleEndpoint(w http.ResponseWriter, req *http.Request) {
      w.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
      json.NewEncoder(w).Encode(people)
  }
  
  // CreatePersonEndpoint creates a new person in the database.
  func CreatePersonEndpoint(w http.ResponseWriter, req *http.Request) {
      w.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
      params := mux.Vars(req)
      var person Person
      _ = json.NewDecoder(req.Body).Decode(&amp;person)
      person.ID = params[&quot;id&quot;]
      people = append(people, person)
      json.NewEncoder(w).Encode(people)
  }
  
  // DeletePersonEndpoint deletes a person from the database.
  func DeletePersonEndpoint(w http.ResponseWriter, req *http.Request) {
      w.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
      params := mux.Vars(req)
      for index, item := range people {
          if item.ID == params[&quot;id&quot;] {
              people = append(people[:index], people[index+1:]...)
              break
          }
      }
      json.NewEncoder(w).Encode(people)
  }
  
  // SeedData is just for this example and mimics a database in the 'people' variable.
  func SeedData() {
      people = append(people, Person{ID: &quot;1&quot;, Firstname: &quot;John&quot;, Lastname: &quot;Smith&quot;, Location: &amp;Location{City: &quot;London&quot;, Country: &quot;United Kingdom&quot;}})
      people = append(people, Person{ID: &quot;2&quot;, Firstname: &quot;John&quot;, Lastname: &quot;Doe&quot;, Location: &amp;Location{City: &quot;New York&quot;, Country: &quot;United States Of America&quot;}})
  }
  
  func main() {
      router := mux.NewRouter()
      SeedData()
      router.HandleFunc(&quot;/people&quot;, GetPeopleEndpoint).Methods(&quot;GET&quot;)
      router.HandleFunc(&quot;/people/{id}&quot;, GetPersonEndpoint).Methods(&quot;GET&quot;)
      router.HandleFunc(&quot;/people/{id}&quot;, CreatePersonEndpoint).Methods(&quot;POST&quot;)
      router.HandleFunc(&quot;/people/{id}&quot;, DeletePersonEndpoint).Methods(&quot;DELETE&quot;)
      fmt.Println(&quot;Listening on http://localhost:12345&quot;)
      fmt.Println(&quot;Press 'CTRL + C' to stop server.&quot;)
      log.Fatal(http.ListenAndServe(&quot;:12345&quot;, router))
  }
  </code></pre>
  <p>Here is my <code>main_test.go</code> file.</p>
  <pre class="lang-golang prettyprint-override"><code>package main
  
  import (
      &quot;fmt&quot;
      &quot;net/http&quot;
      &quot;net/http/httptest&quot;
      &quot;testing&quot;
  )
  
  func TestGetPeopleEndpoint(t *testing.T) {
      req, err := http.NewRequest(&quot;GET&quot;, &quot;/people&quot;, nil)
      if err != nil {
          t.Fatal(err)
      }
  
      // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
      rr := httptest.NewRecorder()
      handler := http.HandlerFunc(GetPeopleEndpoint)
  
      // Our handlers satisfy http.Handler, so we can call their ServeHTTP method
      // directly and pass in our Request and ResponseRecorder.
      handler.ServeHTTP(rr, req)
  
      // Trying to see here what is in the response.
      fmt.Println(rr)
      fmt.Println(rr.Body.String())
  
      // Check the status code is what we expect.
      if status := rr.Code; status != http.StatusOK {
          t.Errorf(&quot;handler returned wrong status code: got %v want %v&quot;,
              status, http.StatusOK)
      }
  
      // Check the response body is what we expect - Commented out because it will fail because there is no body at the moment.
      // expected := `[{&quot;id&quot;:&quot;1&quot;,&quot;firstname&quot;:&quot;John&quot;,&quot;lastname&quot;:&quot;Smith&quot;,&quot;location&quot;:{&quot;city&quot;:&quot;London&quot;,&quot;country&quot;:&quot;United Kingdom&quot;}},{&quot;id&quot;:&quot;2&quot;,&quot;firstname&quot;:&quot;John&quot;,&quot;lastname&quot;:&quot;Doe&quot;,&quot;location&quot;:{&quot;city&quot;:&quot;New York&quot;,&quot;country&quot;:&quot;United States Of America&quot;}}]`
      // if rr.Body.String() != expected {
      //  t.Errorf(&quot;handler returned unexpected body: got %v want %v&quot;,
      //      rr.Body.String(), expected)
      // }
  }
  </code></pre>
  <p>I appreciate that I am probably making a beginner mistake, so please take mercy on me. I have read a number of blogs testing mux, but can't see what I have done wrong.</p>
  <p>Thanks in advance for your guidance.</p>
  <h3>UPDATE</h3>
  <p>Moving my SeeData call to <code>init()</code> resolved the body being empty for the people call.</p>
  <pre class="lang-golang prettyprint-override"><code>func init() {
      SeedData()
  }
  </code></pre>
  <p>However, I now have no body returned when testing a specific id.</p>
  <pre class="lang-golang prettyprint-override"><code>func TestGetPersonEndpoint(t *testing.T) {
      id := 1
      path := fmt.Sprintf(&quot;/people/%v&quot;, id)
      req, err := http.NewRequest(&quot;GET&quot;, path, nil)
      if err != nil {
          t.Fatal(err)
      }
  
      // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
      rr := httptest.NewRecorder()
      handler := http.HandlerFunc(GetPersonEndpoint)
  
      // Our handlers satisfy http.Handler, so we can call their ServeHTTP method
      // directly and pass in our Request and ResponseRecorder.
      handler.ServeHTTP(rr, req)
  
      // Check request is made correctly and responses.
      fmt.Println(path)
      fmt.Println(rr)
      fmt.Println(req)
      fmt.Println(handler)
  
      // expected response for id 1.
      expected := `{&quot;id&quot;:&quot;1&quot;,&quot;firstname&quot;:&quot;John&quot;,&quot;lastname&quot;:&quot;Smith&quot;,&quot;location&quot;:{&quot;city&quot;:&quot;London&quot;,&quot;country&quot;:&quot;United Kingdom&quot;}}` + &quot;\n&quot;
  
      if status := rr.Code; status != http.StatusOK {
          message := fmt.Sprintf(&quot;The test returned the wrong status code: got %v, but expected %v&quot;, status, http.StatusOK)
          t.Fatal(message)
      }
  
      if rr.Body.String() != expected {
          message := fmt.Sprintf(&quot;The test returned the wrong data:\nFound: %v\nExpected: %v&quot;, rr.Body.String(), expected)
          t.Fatal(message)
      }
  }
  </code></pre>
  <p>Moving my SeedData call to <code>init()</code> resolved the body being empty for the people call.</p>
  <pre class="lang-golang prettyprint-override"><code>func init() {
      SeedData()
  }
  </code></pre>
  <p>Creating a new router instance resolved the issue with accessing a variable on a route.</p>
  <pre class="lang-golang prettyprint-override"><code>rr := httptest.NewRecorder()
  router := mux.NewRouter()
  router.HandleFunc(&quot;/people/{id}&quot;, GetPersonEndpoint)
  router.ServeHTTP(rr, req)
  </code></pre>