RSpec.describe "loop test" do
it "use each to test" do
[1, 3, 5].each do |num|
expect(num).to be_odd
end
end
end
這樣也沒有什麼問題,但當 RSpec 有提供給你更好的方法的時候,我們就沒有必要自己來跑迴圈。
這樣很容易讓測試的閱讀性變得很困難,所以接下來的這個 all matcher 可以一次的測試所有的值,而且讓語法變得非常易讀!
all matcher
ruby
1 2 3 4 5 6 7 8 9
RSpec.describe "all matcher" do
it "check every value" do
expect([1, 3, 5]).to all(be_odd)
expect([1, 3, 6, 5, 8]).to all(be_an(Integer))
expect([1, 3, 4, 7, 9]).to all(be < 10)
expect([], [], []).to all(be_empty)
expect([2, 4, 6]).to all(be_even)
end
end
我們可以看到 all 後面可以接收所有 RSpec 的 matcher。
接著我們可以再用一行流的方式來練習看看~
all matcher one line version
ruby
1 2 3 4 5 6 7
RSpec.describe "all matcher" do
it [1, 3, 5] do
it { is_expected_to all(be_odd) }
it { is_expected_to all(be < 10) }
it { is_expected_to all(be_an(Integer)) }
end
end
be matcher ( nil, falsy, truthy)
這個 be matcher 和之前提到的 be 不太一樣,這個主要是拿來測試 true & false 的值!
而在 Ruby 的世界中,只有兩個東西不是 true 的,就是 false & nil。
意思就是所有的物件都是 true 的,都是正向的。
我們可以用一些簡單的示範來看看:
condition flow
ruby
1 2 3 4 5 6
> if "-1"
> p 'true'
> else
> p 'false'
> end
> # 'true'
RSpec.describe "be matcher" do
it "can test true" do
expect(true).to be_truthy
expect("-100").to be_truthy
expect(:test).to be_truthy
expect([-50, -100]).to be_truthy
expect({}).to be_truthy
expect(0).to be_truthy
end
it "can test nil false" do
expect(nil).to be_falsy
expect(false).to be_falsy
# 整個 Ruby 世界中唯二的 falsy 物件
end
end
相信上面這個範例就可以很清楚的理解到這個 matcher 的使用方法啦~
change matcher
這個 matcher 蠻有趣的,但實用度比較低,我就使用範例稍微介紹一下!
change matcher
ruby
1 2 3 4 5 6 7 8 9
RSpec.describe "change matcher" do
subject {[1, 2, 3]}
it "check object change state" do
expect { subject.push(4) }.to change { subject.length }.from(3).to(4)
expect { subject.push(4) }.to change { subject.length }.by(1)
expect { subject.pop }.to change { subject.length }.by(-1)
end
end
RSpec.describe "contain_exactly matcher" do
it "check exactly contain" do
expect([1,2,3]).to contain_exactly(1,3,2)
expect([1,2,3]).to contain_exactly(2,1,2)
expect([1,2,3]).to contain_exactly(3,2,1)
end
end
RSpec.describe "start_with & end_with" do
descirbe "SnoppyDog" do
it "check the substring from begin to end" do
expect(subject).to start_with("Snop")
expect(subject).to start_with("S")
expect(subject).to start_with("SnoppyDo")
expect(subject).to end_with("pyDog")
expect(subject).to end_with("og")
end
it { is_expected_to start_with("Sn") }
it { is_expected_to end_with("Dog") }
end
descirbe [1, 3, 7] do
it { is_expected_to start_with(1, 3) }
it { is_expected_to end_with(3, 7) }
end
end