Category Archives: rspec

rspec let 複数行

describe 'test' do
  // 以下のように複数行でもエラーはでない
  let(:value) {
    test = 1
    test = 2
    test = 1
  }
  describe 'test' do
    it 'test1' do
      expect(value).to eq 1
    end
    describe 'test' do
      let(:value) {2}
      it 'test2' do
        expect(value).to eq 2
      end
    end
  end
end

rspec describe内での変数定義

テストコード

require 'rails_helper'

describe 'test1' do
  value = 1
  it 'test1' do
    expect(value).to eq 1
  end
  describe 'test' do
    value = 2
    it 'test2' do
      expect(value).to eq 2
    end
  end
  describe 'test' do
    it 'test3' do
      expect(value).to eq 1
    end
  end
end

結果

test1も失敗する。ネスト関係にあるdescribe内で定義した
valueになる。変数定義は、beforeもしくはletで行うべき。

test1
  test1 (FAILED - 1)
  test
    test2
  test
    test3 (FAILED - 2)

Failures:

  1) test1 test1
     Failure/Error: expect(value).to eq 1

       expected: 1
            got: 2

       (compared using ==)
     # ./spec/test/test5_spec.rb:6:in `block (2 levels) in <top (required)>'

  2) test1 test test3
     Failure/Error: expect(value).to eq 1

       expected: 1
            got: 2

       (compared using ==)
     # ./spec/test/test5_spec.rb:16:in `block (3 levels) in <top (required)>'

Finished in 0.02535 seconds (files took 3.44 seconds to load)
3 examples, 2 failures

rspec before

テストコード

require 'rails_helper'

describe 'テスト' do
  before do
    p "before!"
  end
  describe 'インスタンス変数' do
    it 'テスト1' do
      User.create
      expect(User.all.count).to eq 1
    end
    it 'テスト2' do
      User.create
      expect(User.all.count).to eq 1
    end
  end
end

結果

各itの前にbeforeが呼び出されている

テスト
  インスタンス変数
"before!"
    テスト1
"before!"
    テスト2

さらにネストしても、beforeは呼び出されるか?

テストコード

require 'rails_helper'

describe 'テスト' do
  before do
    p "before!"
  end
  describe 'テスト' do
    describe 'インスタンス変数' do
      it 'テスト1' do
        User.create
        expect(User.all.count).to eq 1
      end
      it 'テスト2' do
        User.create
        expect(User.all.count).to eq 1
      end
    end
  end
end

結果

ネストしても、各itの前にbeforeが呼び出されている

テスト
  テスト
    インスタンス変数
"before!"
      テスト1
"before!"
      テスト2

rspec letとインスタンス変数の違い

比較

ほとんど変わらない。個人的にはインスタンス変数の方がわかりやすい。

require 'rails_helper'

describe 'インスタンス変数' do
  before do
    @value1 = 1
  end
  it 'テスト' do
    expect(@value1).to eq 1
  end
  describe 'nest1' do
    before do
      @value1 = 2
    end
    it 'テスト' do
      expect(@value1).to eq 2
    end
  end
  describe 'nest2' do
    it 'テスト' do
      expect(@value1).to eq 1
    end
  end
end

describe 'let' do
  let(:value) {1}
  it 'テスト' do
    expect(value).to eq 1
  end
  describe 'nest' do
    it 'テスト' do
      expect(value).to eq 1
    end
  end
end

rspec 配列比較

テスト

require 'rails_helper'

describe "array" do
  before do
    @array = [1,3,2]
  end
  it 'arrayの順番同じ' do
    expect(@array).to match_array([1,2,3])
  end
  it 'arrayの順番異なる' do
    expect(@array).to match_array([1,3,2])
  end
end

describe "hash_array" do
  describe 'true' do
    before do
      @array = [
        {:name=>"test1", :amount=>35} ,
        {:name=>"test2", :amount=>100}
      ]
    end
    it 'arrayの順番同じ' do
      answer = [
        {:name=>"test1", :amount=>35} ,
        {:name=>"test2", :amount=>100}
      ]
      expect(@array).to match_array(answer)
    end
    it 'arrayの順番異なる' do
      answer = [
        {:name=>"test2", :amount=>100} ,
        {:name=>"test1", :amount=>35}
      ]
      expect(@array).to match_array(answer)
    end
  end
  describe 'false' do
    before do
      @array = [
        {:name=>"test1", :amount=>35} ,
        {:name=>"test2", :amount=>100}
      ]
    end
    it 'レコードが足りないケース' do
      // わざとエラーを起こしてみる。差分もわりと見やすく返してくれる
      answer = [
        {:name=>"test1", :amount=>35}
      ]
      expect(@array).to match_array(answer)
    end
  end
end

検証結果の表示のされ方

1) インスタンス変数 テスト
   Failure/Error: expect([1,2,3]).to match_array([1,2])

     expected collection contained:  [1, 2] # 解答
     actual collection contained:    [1, 2, 3] # 比較対象
     the extra elements were:        [3] # 差分

参考

http://takatoshiono.hatenablog.com/entry/2014/12/15/193628

before do

各itの前に毎回実行する

code

require 'rails_helper'

describe 'test' do
  before do
    p "hello"
  end
  describe 'test' do
    5.times do
      it 'test' do
        expect(1).to eq 1
      end
    end
  end
end

結果

test
  test
"hello"
    test
"hello"
    test
"hello"
    test
"hello"
    test
"hello"
    test

itの前に1回だけ実行する

code

require 'rails_helper'

describe 'test' do
  before(:all) do // :allオプションを追加
    p "hello"
  end
  describe 'test' do
    5.times do
      it 'test' do
        expect(1).to eq 1
      end
    end
  end

結果

test
"hello"
  test
    test
    test
    test
    test
    test

スコープ

require 'rails_helper'

describe 'test1' do
  before(:all) do
    @value = "hello"
  end
  describe 'test' do
    5.times do
      it 'test' do
        p @value // @valueよびだせる
        expect(1).to eq 1
      end
    end
  end
end

describe "test2" do
  it 'test' do
    p @value // スコープ外で@value=nil
  end
end

変数呼び出し

code

require 'rails_helper'

describe 'test1' do
  before(:all) do
    @value1 = "hello"
  end
  describe 'test' do
    before(:all) do
      @value2 = "hello"
    end
    5.times do
      # itの前だとnil
      p @value1
      p @value2
      it 'test' do
        # itの中で正しくよびだせる
        p @value1
        p @value2
        expect(1).to eq 1
      end
    end
  end
end

結果

nil
nil

test1
  test
"hello"
"hello"
    test

rspec let

使い方

require 'rails_helper'

describe 'test1' do
  // 変数定義
  let(:value){"hello!"}
  describe 'test1-1' do
    describe 'test1-1-1' do
      it 'test' do
        // 下の階層でも呼び出せる
        p value
      end
    end
  end
end

インスタンス変数の場合

インスタンス変数のスコープ狭い。
下の階層では使えない。なので、その場合はlet使う方がいい。

describe 'test1' do
  @value = "hello!"
  describe 'test1-1' do
    p @value
  end
end

rspec 事例

事例

itごとに、dbは削除される。

コード事例

require 'rails_helper'

describe 'one' do
  it 'one' do
    User.create
    User.create
    expect(User.all.count).to eq 2
  end
  it 'two' do
    User.create
    User.create
    expect(User.all.count).to eq 2
  end
end

describe 'three' do
  it 'three' do
    User.create
    User.create
    expect(User.all.count).to eq 2
  end
end

describe 'four' do
  // itの外でレコードを作る場合は、beforeに入れる
  before do
    User.create
    User.create
  end
  it 'three' do
    expect(User.all.count).to eq 2
  end

  it 'three' do
    User.create
    expect(User.all.count).to eq 3
  end
end

rspec データクリア

gemインストール

group :development, :test do
  gem 'database_cleaner'
end

spec/spec_helper.rb

config.before(:suite) do
  DatabaseCleaner.strategy = :transaction
  DatabaseCleaner.clean_with(:truncation)
end