woshidan's blog

そんなことよりコードにダイブ。

RSpecでクラスの挙動や定数をテスト用のダミーにする、見慣れなかったマッチャ、普段は実行しないテストのスキップ、などの話

参加しているプロジェクトのRSpecを見ていたら見慣れないことがいろいろあったので、復習しておきます。

RSpecでクラスの挙動をダミー用のものにする

target_obj = double("target_obj") # initializeの文字のほうに深い意味はないらしい
target_obj.stub(:string) { "Stub test" }
# 以上は上と同じ target_obj = double("target_obj", :string => "Stub test")

allow(target_obj)to receive(:post) # ダミーオブジェクトである target_obj に postメソッドを生やす

# テストしたいメソッドの中で使われているクラスを初期化したらテスト用に用意したダミー実装が使われるようにする
allow(Real::Target).to receive(:new).and_return(target_obj)

# def testing_method
#   Real::Target.new.copy.string
# end

expect(testing_method).to eq "Stub test"

# 所定のspecでだけ定数を置き換えたい
stub_const("TARGET::CONST", 100)

参考

http://web-k.github.io/blog/2012/10/02/rspec-mock/ https://qiita.com/jnchito/items/640f17e124ab263a54dd

http://codenote.net/ruby/rspec/1800.html https://relishapp.com/rspec/rspec-mocks/docs/mutating-constants

match_array マッチャ便利かも

ActiveRecordから要素を取り出してくるけど、テスト用にベタがきする値と順序が一致していないので汚いコードを書いて... という記憶があったのでよさそう。

参考

https://qiita.com/jnchito/items/a4a51852c2c678b57868

RSpecで普段は実行しないテストをスキップする

describe Hoge do
  it "heavy test", type: :model, very_heavy_tests: true do # スキップ用のオプションはRails5で追加された type オプションの後に書きます
    hoge.should eq(fuga)
  end
end

describe Hoge do
  it "normal test", type: :model do # 書いてない場合は very_heavy_tests: false 扱いでこのテストは普段から実行される
    hoge.should eq(fuga)
  end
end
RSpec.configure do |c|
  c.filter_run_excluding :very_heavy_tests => true
end

参考

https://qiita.com/semind/items/cffd5c9e7ef9a108c871

現場からは以上です。