该文章同步发布於:我的部落格
昨天我们实作了把 example
给拆开,并且让整个测试更具备逻辑。
今天我们要让程序码更乾净,解决一些不断重复的程序码,在我刚开始学习时,觉得多打一两行也还好吧。
到现在要我打移动距离去改三个字都让我觉得痛苦,如果今天放大成 100 倍呢?我相信如果一个小小的改动要连续做一百次,应该是不会有人愿意吧哈哈!
下面是我们昨天实作的测试码,接着我们要来重构它。
重构的要点在於减少不必要的程序码,加速效能,让他看起来更舒服!
RSpec.describe Burger do
it "has cheese" do
burger = Burger.new('Beef', 'Cheddar')
expect(burger.cheese).to eq('Cheddar')
end
it "has meat" do
burger = Burger.new('Beef', 'Cheddar')
expect(burger.meat).to eq('Beef')
end
end
这段程序码,最需要改动的地方就在於第 3, 8 行,因为是完全一模一样的程序码,所以可以使用我们要介绍的 Before hooks
来解决这件事情!
先上完成的程序码:
RSpec.describe Burger do
before do
@burger = Burger.new('Beef', 'Cheddar')
end
it "has cheese" do
expect(@burger.cheese).to eq('Cheddar')
end
it "has meat" do
expect(@burger.meat).to eq('Beef')
end
end
上面的程序码会得到 PASS!
接着我们来解释这到底是什麽作用,首先这个 before
的原型应该是这样:
before(:example) do
...
end
意思就是指,在每一个 example
前,做这件事情!应该是一个很好懂的方法,也非常实用,当然里面的 :example
可以做改变,这是更进阶的写法,之後会再提到!
所以我们完全不写参数给他的话,他就会自动的认定要在每一个 example
前执行 block 里面的内容!
这边示范为什麽要提到每一个 example
呢?
我们在 before
的 block 里面加上一段会印出来的文字。
RSpec.describe Burger do
before do
p 'Hello, this is before hooks'
end
it "has cheese" do
burger = Burger.new('Beef', 'Cheddar')
expect(burger.cheese).to eq('Cheddar')
end
it "has meat" do
burger = Burger.new('Beef', 'Cheddar')
expect(burger.meat).to eq('Beef')
end
end
接着我们来看 Out put !
很明显地,他在每一个 example
前执行!
所以先前的测试代码,在进入每一个 example
前,都会有一个实体变数 @burger
产生并一同加入 example
里面!
那至於为什麽要使用 @burger
而不是 burger
呢?
这就牵扯到 Ruby 变数的作用域问题,我们不深入的讨论这件事,但大致上来说,我们可以把一个 block 想像成一个新的领地,若你不加上 @
这个符号成为实体变数,你是没有穿梭 block 的能力!
上面的方法是 RSpec 提供给我们的方法,但 RSpec 是可以直接写 Ruby Code 的,所以我们动动小脑筋,要怎麽做到和 before hook
一样的效果呢?
上代码:
RSpec.describe Burger do
def burger
Burger.new('Beef', 'Cheddar')
end
it "has cheese" do
expect(burger.cheese).to eq('Cheddar')
end
it "has meat" do
expect(burger.meat).to eq('Beef')
end
end
不要怀疑喔!这样得程序码也会过关喔!
但不熟悉 Ruby 的人一定想说你在写三小... 但这真的会动,虽然不会有人这样写,因为後续会造成特殊的问题,但这也是一个方法啦,如果你确定你的数值不会有任何的改变,还是用 before hooks
吧~
他在读取到第 7 行的时候呼叫了 burger
这个我们定义的方法,而在 Ruby 中最後一行可以不用写 return
, 所以他会自动的 return 一个 burger 物件。
所以我们可以这样看第 7 行
expect(Burger.new('Beef', 'Cheddar').cheese).to eq('Cheddar')
这是他会动的原因,但不要这样写,只是稍微提一下!因为这样真的会有问题~
今天介绍了减少程序码的好方法 before
,这将会在之後的 RSpec 生涯中偶尔地出现!
什麽?你说这才偶尔,那干嘛教呢?
哎唷,总是什麽方法都要看过才好啊!你才知道什麽是好,什麽是不好,像今天示范的用原始 Ruby 写的方法,也会动啊,但会遇上变动性的问题。
所以明天将会介绍在 RSpec 里面,遇到变动性问题该怎麽解决?以及最强大的方法 let
也会在明天一并介绍起来~
<<: Material UI in React [Day 22] Data Display (part 2) 分隔线 & 列表
创建App-现界面与连接 经过了十五天的努力,现在就来看看现有的界面功能吧,我依照功能来区分:登入、...
实作待办事项的第三天,今天把切换日期的功能做好就完成啦!!今天会透过路由传递日期像是这样 https...
上一篇介绍过 State Hook 用来储存状态,Effect Hook 则用来处理 functio...
前言 前面已经知道如何抓「台湾证券交易所」的每日收盘行情 CSV 档,接下来要处理资料,并存入 DB...
在昨天将 index 成功推上 Github 後,今天该让他有点东西了。 打开 VSCODE 後 按...