LoginSignup
4
4

More than 5 years have passed since last update.

gojiのレスポンス結果をテストする

Last updated at Posted at 2015-06-21

revelには,e2eテストのようなtest機能があるのだが、
これをgojiでも同じようなことをやりたいとき。

main.go
package main

import (
  "fmt"
  "net/http"

  "github.com/zenazn/goji"
  "github.com/zenazn/goji/web"
)

func main() {
  serve()
}

func serve() {
  goji.Get("/", func(c web.C, w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, `{"foo":"bar"}`)
  })
  goji.Serve()
}

上みたいな場合、テストの前にgoji.Serve()をgoroutineで起動してからテストを実行する。

main_test.go
package main

import (
  "encoding/json"
  "flag"
  "net"
  "net/http"
  "os"
  "testing"
  "time"
)

const bind = ":11251"

// テストを走らせる前に、goji.Serve()を起動する
func TestMain(m *testing.M) {
  flag.Set("bind", bind)
  go func() {
    serve()
  }()

  ready()
  os.Exit(m.Run())
}

// サーバー側のport確認
func ready() {
  timeout := make(chan struct{}, 1)
  go func() {
    time.Sleep(10 * time.Second)
    timeout <- struct{}{}
  }()

  for {
    select {
    case <-time.After(100 * time.Millisecond):
      if _, err := net.Dial("tcp", "127.0.0.1"+bind); err == nil {
        return
      }
    case <-timeout:
      panic("timeout")
    }
  }
}

// リクエストを投げて、結果のJSONが正しいかを確認する
func TestHome(t *testing.T) {
  resp, err := http.Get("http://127.0.0.1" + bind)
  if err != nil {
    t.Fatal(err)
  }
  defer resp.Body.Close()

  var ms map[string]interface{}
  if err := json.NewDecoder(resp.Body).Decode(&ms); err != nil {
    t.Fatal(err)
  }
  if ms["foo"] != "bar" {
    t.Errorf("foo: have %v; want bar", ms["foo"])
  }
}

これでgo testでテスト実行できる。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4