Day 15 Matcher 基础三兄弟!

该文章同步发布於:我的部落格

今天会开始介绍许多好用的 Matcher 也就是配对仔,从开始到现在我们都只使用过 eq 这种用法!

其实还有很多有趣的 Matcher 可以使用!

今天会介绍三种不同的 Matcher 但又很相似的,分别是 eq eql be

eq Matcher

eq 是我们最常使用的 Matcher,其概念也非常简单,就是单纯的比较 value,而不比较 type !

我们可以用一些示范来比喻一下!

RSpec.describe "eq matcher" do
  let(:a) { 5.0 }
  let(:b) { 5 }
  
  it 'only tests for value' do
    expect(a).to eq(5)
    expect(b).to eq(5.0)
    expect(a).to eq(b)
  end
end

这会是一个全部通过的情况!我们也说过 eq 只看值,不看型别。

为什麽会这样说呢?因为其实在 Ruby 的世界中 5 and 5.0 两个人是属於不同的类别!

若是在 IRB 中试试看:

> 5.class
> Integer
> 5.0.class
> Float

在 Ruby 的整数和浮点数是不同的类别,自然而然也不会是同一个 type!

eq 会略过型别的比对,专注在值是否吻合!

而一直强调型别,那会根据型别来判断的 Matcher 是哪个呢?

eql Matcher

虽然只差了一个 l 的字母,但在处理的严谨度上就完全不相同了!

如果一样使用刚刚的范例,但改用 eql 来看看会发生什麽事情?

RSpec.describe "eql matcher" do
  let(:a) { 5.0 }
  let(:b) { 5 }

  it 'tests for value and type' do
    expect(a).to eql(5)
    expect(b).to eql(5.0)
    expect(a).to eql(b)
  end
end

没通过的结果:

他会告诉你,55.0 是不相同的东西,测试不通过!!!

你会想说,这样有什麽差别啦,现实世界中 5 就是 5.0 啦~

但情境如果是在处理精密的汇率或是税率等等,使用 eq 来做 Matcher 是不是会有一点草率呢?

使用 eql 能够帮你在撰写方法的时候考虑得更多!你也可以想像成严格模式啦~

因为它必须是 相同的 value 以及 相同的类别 才能被认定为相同!

接下来我想介绍更严格的一个 Matcher,他不只要你是同一个型别,他还要你是同一个物件!

equal Matcher & be Matcher

会放在一起讲的原因是 equal 等同於 be,所以接下来我们会一起示范这要怎麽用!

但在放上范例之前,我想提一个概念:

equality 意思是在确认两个物件在基本的设计上一样的!

identity 意思是在确认两个物件是同一个物件!

为什麽会讲这样的概念呢?因为 equal 就是 identity 的概念,而上面的 eq eql 都像是 equality 的概念!

我们换个类比的方法,假设我在一条大街上,和我隔壁的邻居盖了一间一模一样的房子 ( 是真的一模一样,包含窗框、草皮、房门等等 )

你心里会说,这两个房子长得一模一样欸!但你不会说这是同一个房子,对吧?

就算他们在怎麽像,像到完全看不出来差别,你还是能用地址来做判断,他们还是两间房子!

等等示范的 equal 就是在帮你检查是不是同一个地址,同一个房子的概念!

eq eql 都只是看看照片说,这两个根本一模一样嘛~

废话不多说,我们直接上 Code 吧!

RSpec.describe "equal matcher & be matcher" do
  let(:a) { [7, 7, 7]}
  let(:b) { [7, 7, 7]}
  let(:c) { a }
  
  it "test for object identity" do
    expect(a).to eq(b)
    expect(a).to eql(b)
    
    expect(a).to equal(c)
    expect(a).not_to equal(b)
  end
end

上面是一个会全部通过的测试!

这边的 c 变数,指向 a 变数,这代表着什麽?

我把我家的地址填得和你家地址一样,我们两个是一模一样在同一个地方的物件!

ab 在值以及型别上来看,都一模一样,但他们在记忆体中的地址却不相同,我们可以故意让测试坏掉来看看 OutPut 是什麽?

我们让 a equal b 来试试看!

错误的提示:

可以看到两个在 Array 的记忆体位置是不相同的 ( 一个是 2800, 一个是 2820 ),这就像是房子的案例一样,我们虽然一样,但终究是两个个体!

下面的提示也有告诉你,这是在比较物件的 identity

刚刚范例上都使用 equal,但其实你也可以用 be 比较省力喔~

小结

重新复习一下三者的不同之处!

eq:单纯比较值,不在意型别

eql:比较值以及型别

equal 以及 be:比较值,型别,记忆体位置(是否为同一个物件)

希望以後大家在使用的时候,可以根据要测试的严谨程度来决定要使用哪一个 Matcher 喔!

这三个都是非常基础的 Matcher 但却常常不知道错在哪,希望这篇文章可以帮助到你~


<<:  【Day18】[资料结构]-堆积Heap-实作

>>:  IOS、Python自学心得30天 Day-26 Firebase部分

【Day 04】LeetCode:Fizz Buzz ( 用 JavaScript 学演算法 )

我们透过 LeetCode #412 Fizz Buzz 来实际感受解决问题的过程 ( 题目连结 )...

DAY7:版面配置及基本元件之简介

今天要来说到版面配置的部分! 首先,我们第一个先从”画面设计”开始说起,还记的我们前面说到的吗?关於...

Unity与Photon的新手相遇旅途 | Day14-生成敌人

今天介绍的内容为如何固定位置生成以及随机位置生成敌人。 ...

Day22:Hot Flow - SharedFlow (Part II)

昨天我们使用了 shareIn 将 Flow 转成 SharedFlow, 我们来研究一下这个函式。...

股票下单失败,出现讯息:全额预收

下单-买 Q:股票下单(买)失败,出现讯息:全额预收 A:问营业员,营业员说,可能该股票最近涨浮过大...