“net/smtp” パッケージ の smtp.SendMail1を使ったプログラムで、そのまま動作確認しようとすると、メールサーバーを正しく指定する必要があったり、実際にメールが送信されちゃったりと面倒この上ないと思ってます。
関数の引数などに、同じ func 型で中身は []byte 型の変数に書き込むだけのモックを用意する方法もありますが、実際に送信しないのが気になったり、モックを用意する前提で関数を設定するから規模によってはちょっと冗長に感じたりしました。
なので smtp.SendMail のテストコード2を参考にして、コード上からローカルにダミーの SMTP サーバーを立ててみました。
環境
- golang:1.9.2
実装
- https://play.golang.org/p/8mfrqNVWTPK
やってること
127.0.0.1:%d で待ち受け
以下を goroutine で実施
接続要求が着たら繋いで、予め用意しておいたメッセージを送りつける
メッセージを送った後はクライアントからメッセージが届くので受け取る
受け取ったら予め用意しておいたバッファーに格納
354 を送った後はクライアントからのメール本文が一行ごとに届くので受け取り続けて
. だけが着たらメール本文終了でメール送信の終了処理
上記の goroutine が終わったら受け取ったメールデータを返却してくれる関数を戻り値として返却
ただし goroutine 内でエラーが発生したらそっちを返却する
第1引数以降は可変引数で、指定するとSMTPサーバーレスポンスを変更できるようにしてます
デフォルトでは認証付きのメール送信
第2引数で 550 を指定すると接続段階でエラー
それ以降は SMTP の仕様を調べてください
言い訳だけど、テストコード用の適当実装なので getReceivedData() を呼ばなかったりそもそも接続要求しないと多分メモリリークする (getReceivedData() 呼んでもするかな..?)
https://golang.org/pkg/net/smtp/#SendMail ↩
https://golang.org/src/net/smtp/smtp_test.go ↩