2017-03-13 6 views
0

以下のようなhandlerfuncがあるとします。テストのためにオブジェクトをラップするインターフェイスを「模擬する」、または注入するための最良の方法は何ですか?次に、ルータで、このようなメーラーを呼び出すインタフェースをモックするためのメソッド

type Mailer interface { SendMail() } 

func HandlerWithMailer(m Mailer) http.handlerFunc { 
    return func(w http.ResponseWriter, r *http.Request) { 
     user := GetUserFromContext(r.Context()) 
     if created := user.GetOrCreate(); created { 
      m.SendEmail(...) 
      return 
     } else {     
      w.Write([]byte("Hello User!")) 
     } 
    } 
} 

(使用httprouter)::私はで来た

func GetOrCreateUser(w http.ResponseWriter, r *http.Request) { 
    user := GetUserFromContext(r.Context()) 
    if created :=user.GetOrCreate(); created { 
     smtp.SendEmail(...) 
     return 
    } else { 
     w.Write([]byte("Hello User!")) 
    } 
} 

唯一の方法は、これを実行するように思わ

m := mailer.New() // assuming this returns a new mailer 
r := httprouter.New() 
r.GET("/mailer", HandlerWithMailer(m)) 

これはインターフェイスを実装する構造体を作ることでテストでき、テストで呼び出すことができる任意のものを返します。私はこの作品を知っていますが、これがGoでテストするのが好ましい方法であるか、これを達成するための他の方法があるかどうかは疑問です。

答えて

1

私はそうのような構造体からの私のハンドラを呼び出します。

type Handlers struct { 
    mailer *Mailer 
} 

func(h *Handlers) GetOrCreateUser(w http.ResponseWriter, r *http.Request) { 
    user := GetUserFromContext(r.Context()) 
    if created :=user.GetOrCreate(); created { 
     h.mailer.SendEmail(...) 
     return 
    } else { 
     w.Write([]byte("Hello User!")) 
    } 
} 

この方法で、あなたが使用したいMailerの実装と構造体をinstansiateすることができます。

m := mailer.New() // assuming this returns a new mailer 
h := Handlers{&m} 

r := httprouter.New() 
r.GET("/mailer", h.HandlerWithMailer) 

とあなたのテストで

m := mockMailer.New() // assuming this returns a new mailer 
h := Handlers{&m} 

r := httprouter.New() 
r.GET("/mailer", h.HandlerWithMailer) 
関連する問題