RSpec3の対応(参考:RSpec 3の重要な変更 - 有頂天Ruby)

RSpec 3の重要な変更 - 有頂天Ruby

こちらを見ながら手元のテストをRSpec3に対応していました。 一時の慣れで済むのでしょうが、色々変わって大変です。

リンク先メモ

メジャーな修正内容は省略。

フックスコープのための新しい名前: :example と :context

each / all / suite

  c.before(:each)  { } # 全てのテストスイート中のそれぞれのexampleの前に実行される
  c.before(:all)   { } # それぞれのトップレベルのグループの最初のexampleの前に実行される
  c.before(:suite) { } # 全てのspecファイルがロードされたあと、最初のspecが実行される前に一度だけ実行される

each => example
all => context
 

DSLメソッドがexampleを引数として渡す

exampleなんて知らなかった。色々取得できます。

#RSpec2
describe MyClass do
  before(:each) { puts example.metadata }
end


#RSpec3
  before(:example) { |ex| puts ex.metadata }
  let(:example_description) { |ex| ex.description }

  it 'exampleにアクセス' do |ex|
    # exを使う
  end

 

example groupの新しいエイリアス: xdescribe, xcontext, fdescribe, fcontext

xつけるとskip、fつけるとfocus
 

ワンライナーのための新しいAPI: is_expected

# rspec2
it { should allow_mass_assignment_of(:title) }

# rspec3
it { is_expected.to allow_mass_assignment_of(:title) }

should_not は is_expected.not_to
 

新しいoutputマッチャー

以前は、こういうのを用意しておいて

# spec_helper.rb
def capture(stream)
  begin
    stream = stream.to_s
    eval "$#{stream} = StringIO.new"
    yield
    result = eval("$#{stream}").string
  ensure
    eval("$#{stream} = #{stream.upcase}")
  end

  result
end

stdoutをすり替えるようなことをしていたのですが

# RSpec2
      it 'display with expanding name column' do
        expect(capture(:stdout) { @executor.search('long_pod_name') }).to eq <<-'EOS'.unindent
          |Name(Ver)                                      Score  Star  Fork
          |--------------------------------------------- ------ ----- -----
          |AFNetworking (2.2.3)                           28241 11941  3260
          |ACECoreDataNetworkTableViewController (0.0.2)      2     2     0
          |AKANetworkLogging (0.1.0)                          1     1     0
        EOS
      end

似たようなものがデフォルトで用意され、こういう書き方ができるようになりました。

# RSpec3
      it 'display with expanding name column' do
        res = <<-'EOS'.unindent
          |Name(Ver)                                      Score  Star  Fork
          |--------------------------------------------- ------ ----- -----
          |AFNetworking (2.2.3)                           28241 11941  3260
          |ACECoreDataNetworkTableViewController (0.0.2)      2     2     0
          |AKANetworkLogging (0.1.0)                          1     1     0
        EOS
        expect { @executor.search('sqlite') }.to output(res).to_stdout
      end

 

Booleanマッチャーの名前がかわりました

be_truthyとbe_false (be_true/be_falseと同じように読めるが、ほんとにtrue/falseのときしか通らない)  

他やってて気づいたこと

its

its がrspec-its に切り出されました。

gem 'rspec-its'

して
require 'rspec/its'
すればok。  

subjectと併用時のshould

(itsの例ですがitでも同じ)
これはwarningの対象外です。これをexpectで書くとなんとまぁ残念なことになるのですがshouldと書いても大丈夫なようです。

    subject { @agent }
    its(:proxy_addr) { should eq '192.168.1.99' }
    its(:proxy_user) { should eq 'proxy_user' }
    its(:proxy_pass) { should eq 'proxy_pass' }
    its(:proxy_port) { should eq 9999 }