Help us understand the problem. What is going on with this article?

golang で実際にメール送信せず smtp.SendMail を試すためのモック作り

More than 1 year has passed since last update.

"net/smtp" パッケージ の smtp.SendMail1を使ったプログラムで、そのまま動作確認しようとすると、メールサーバーを正しく指定する必要があったり、実際にメールが送信されちゃったりと面倒この上ないと思ってます。

関数の引数などに、同じ func 型で中身は []byte 型の変数に書き込むだけのモックを用意する方法もありますが、実際に送信しないのが気になったり、モックを用意する前提で関数を設定するから規模によってはちょっと冗長に感じたりしました。

なので smtp.SendMail のテストコード2を参考にして、コード上からローカルにダミーの SMTP サーバーを立ててみました。

環境

  • golang:1.9.2

実装

やってること

  1. 127.0.0.1:%d で待ち受け
  2. 以下を goroutine で実施
    1. 接続要求が着たら繋いで、予め用意しておいたメッセージを送りつける
    2. メッセージを送った後はクライアントからメッセージが届くので受け取る
      • 受け取ったら予め用意しておいたバッファーに格納
    3. 354 を送った後はクライアントからのメール本文が一行ごとに届くので受け取り続けて
    4. . だけが着たらメール本文終了でメール送信の終了処理
  3. 上記の goroutine が終わったら受け取ったメールデータを返却してくれる関数を戻り値として返却
    • ただし goroutine 内でエラーが発生したらそっちを返却する
  • 第1引数以降は可変引数で、指定するとSMTPサーバーレスポンスを変更できるようにしてます

    • デフォルトでは認証付きのメール送信
    • 第2引数で 550 を指定すると接続段階でエラー
    • それ以降は SMTP の仕様を調べてください
  • 言い訳だけど、テストコード用の適当実装なので getReceivedData() を呼ばなかったりそもそも接続要求しないと多分メモリリークする (getReceivedData() 呼んでもするかな..?)

tver-technologies
Innovate TVision, Designing Value / テレビ・動画配信の可能性を切り拓き、新しい価値をデザインしていきます。
https://www.tver-tech.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away