rspecでなんでも通すモックを定義してみた
rspecを初めて使ったので、モックを使うメモ
gemのmailを使ってGmailを送るメソッドがある。
require "mail" # ... def send_alert_to_gmail(content) mail = Mail.new mail.from = CONFIG['email'] mail.to = CONFIG['to'] mail.charset = "UTF8" mail.body = content mail.delivery_method :smtp, { :address => 'smtp.gmail.com', :port => 587, :domain => 'smtp.gmail.com', :user_name => CONFIG['email'], :password => CONFIG['password'], :authentication => :plain, :enable_starttls_auto => true } mail.deliver # ここを発行したくない end # ...
これのテストコード(一部)
# ... describe '#send_to_gmail' do it 'can send' do mail = mock(:mail).as_null_object # とりあえずなんでも通しちゃうメソッドを定義 mail.should_receive(:deliver).once # 一回だけ呼ばれるメソッド Mail.stub(:new) { mail } Logger.send_alert_to_gmail "yeah!" # mail.deliver を含むメソッド end end
このように外部に作用する(mailを送る)アクションを外に逃すようなアクションを stub out という、らしい。
これはたぶん良い例とは言えない。本当はメールを送るまでのアクションもチェックしたかったのだが、null_objectを定義すると全部逃がしてしまう。関数内部でMailへのアクションがほとんどを占める関数なので、このテストには不適な気がする。
ちなみにmail自体がモックの仕組みを持っている(MailTester)のだが、壊れていた。Exampleのテストが失敗する。
今回は動くコードができたので多少は仕方ないとしても、Issueが100件以上無視されてるモジュールを使うのはやめようとおもった。
でもmailはRails内部でも使われてるらしい。怖い。