RSpecテストでrailsの設定を変更して、後でもとに戻したい

投稿者: Anonymous

やりたいこと:RSpecのテストの途中でrailsの設定を変更して、後でもとに戻したい

例えば、特定の用途のメール送信に使う独自のdelivery_methodを作ってあって、特定のテスト内ではこれを有効にしてテストしたい、という場合。

最初のアイデア

context 'my_super_methodを使うケース' do
  before do
    ActionMailer::Base.delivery_method = :my_super_method
  end
  after do
    ActionMailer::Base.delivery_method = :test
  end
  it 'my_super_methodはxxな振る舞いをする' do
    # my_super_methodを使ったふるまいのテスト
  end
end

問題

 ActionMailer::Base.delivery_methodが:testであることを前提にしている。もしこれが他の値になっていたら、他のテストの挙動を壊してしまう

次のアイデア

 テスト実行前の ActionMailer::Base.delivery_method を保存しておきます

context 'my_super_methodを使うケース' do
  __keeped_method = nil
  before do
    __keeped_method = ActionMailer::Base.delivery_method
    ActionMailer::Base.delivery_method = :my_super_method
  end
  after do
    ActionMailer::Base.delivery_method = __keeped_method
  end
  it 'my_super_methodはxxな振る舞いをする' do
    # my_super_methodを使ったテスト
  end
end

beforeとafterで値を共有する必要があるので、外で変数を初期化しました。
byebugで確認する限りうまく動いているのですが、こんなところに変数宣言してよかったっけ。あとで鼻から悪魔出てきたりしない?

「大丈夫、同じようなことしている例があるよ!」とか「コレコレの理由でダメだろう」とか、「こう書けばもっとシンプルに書けるよ」とか、そんなのを教えてください。

なお、my_super_methodは例としてあげただけなので、「ActionMailer::Base.delivery_methodを変更するのではなくて、MySuperMethodクラスに対してテスト書くべき」みたいな枠外のアドバイスはいらないです。

解決

こういうユースケースではインスタンス変数を使うのがポピュラーなのではないでしょうか。

context 'my_super_methodを使うケース' do
  before do
    @original_method = ActionMailer::Base.delivery_method
    ActionMailer::Base.delivery_method = :my_super_method
  end
  after do
    ActionMailer::Base.delivery_method = @original_method
  end
  it 'my_super_methodはxxな振る舞いをする' do
    # my_super_methodを使ったテスト
  end
end
回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *