该文章同步发布於:我的部落格
今天一样继续来介绍实用的 Matcher 和举例~
在一开始写 Ruby 的时候,你可能会想用跑回圈的方式来测试所有的值!
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
可以一次的测试所有的值,而且让语法变得非常易读!
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
。
接着我们可以再用一行流的方式来练习看看~
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
和之前提到的 be
不太一样,这个主要是拿来测试 true
& false
的值!
而在 Ruby 的世界中,只有两个东西不是 true
的,就是 false
& nil
。
意思就是所有的物件都是 true
的,都是正向的。
我们可以用一些简单的示范来看看:
> if "-1"
> p 'true'
> else
> p 'false'
> end
> # 'true'
这边的 -1
虽然看起来像是负面的数值,但他在 Ruby 的世界中依然是一个 true 的物件,所以这边的判断式会走向印出 "true"
。
接着就可以来使用这个 be matcher
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
的使用方法啦~
这个 matcher 蛮有趣的,但实用度比较低,我就使用范例稍微介绍一下!
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
先提一下为什麽我们要用 { }
而不是像平常一样使用 ( )
,是因为如果我们想要对物件执行 Ruby 方法的时候,都像这样 block 的方式!
而他也可以接受不止一行的参数,你可以在里面进行计算,执行原生的 Ruby 方法等等...
而整个 matcher 的重点就在後面很有趣的写法!我们塞了一个数字进去 array 後,subject
的长度从 3 到 4
的过程!就是我们要测试的!
後面补上的 by(1)
写法,就是改变的数值,因为每次都要写 from...to...
实在是太麻烦了,於是 RSpec 也给我们这样的黑魔法来使用!
这个 Matcher
的工作在於确认 确实涵盖的值且不在乎顺序
。
我们用范例来说明!
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
其实非常的简单,他关注的点是里面的内容物是不是都在,但他不在意顺序!
这个其实使用的地方蛮少的,因为自己在写的时候还是希望测试的格式是固定的,也有可能是我自己想不到使用的他的时机~
看到这个英文的开头,应该能够大概猜到他的使用方式!就是要测试这个物件的开头或是他的结尾~
且主要的用法是在 String
Array
身上!
我们来看看范例吧!
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
但他就不像刚刚的 contain_exactly
一样不在意顺序了!
start_with
本身就带有一种方向的感觉,所以我们的 matcher 要给予照着顺序的参数~
Matcher
的数量真的是有够多,当然要怎麽使用端看自己要测试的重点是什麽~
说不定有些冷门的 Matcher
刚刚好很契合你这个测试的目的也说不定!
重点就是多看一些有趣的 Matcher
然後收藏在浅意识中,想到的时候再去查资料就可以了~
<<: Day16:终於要进去新手村了-Javascript-回圈-while
想要制作一个假背包,利用按钮显示背包,再按下按钮关闭背包。 要使用GameObject.SetAct...
这篇是 infrastructure 也可以 for each 第四篇,上次漏发了,今天补发 本章介...
#结语 最後一天,专案完成了,铁人赛完赛 不过第9天就中断了比赛 真的是觉得太~~~~~~~~~~...
函式陈述式与函式表达式差异 函式陈述式 : function num(x) { return x *...
嗨,大家好,由於本人昨天去打了疫苗,然後晚上9点开始被副作用折腾 以至於过了12点不能马上发文 然後...