Day 18 Matcher 介绍 (下)

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

今天将一口气把剩下比较常用的 Matcher 一并介绍起来!

have_attibutes matcher

这个 Matcher 很清楚明了的告诉你是来测验物件的属性的!

我们直接用范例来介绍一下~

class Burger
  attr_reader :meat, :cheese
  
  def initialize(meat, cheese)
    @meat = meat
    @cheese = cheese
  end
end

RSpec.describe "have_attributes matcher" do
  
  describe Burger.new("Beef", "Cheddar")
    it "checks attribute and value" do
      expect(subject).to have_attributes(meat: "Beef")
      expect(subject).to have_attributes(cheese: "Cheddar")
    end
    
    it { is_expected.to have_attributes(meat: "Beef") }
    it { is_expected.to have_attributes(cheese: "Cheddar") }
  end
end

我们针对汉堡这个类别来进行测试,分别检验他的 meat & cheese 属性所给予的值!

进而判断这个属性是否存在,其实这个真的很简单,也没有真的比较特殊的写法,所以就这样简单的用范例来介绍一下~

include matcher

接下来这个对於有学过 Ruby 的人来说,应该是超级好用的一个语法!

而在 RSpec 中也是异曲同工之妙,就是检查 字串 阵列 Hash 中,所包含的字串、数字或是 key & value 这样的用法!

我们就用范例来更清楚的了解一下吧!

RSpec.describe "include matcher" do

  describe "yummy burger" do
    it "checks substring" do
       expect(subject).to include("yummy")
       expect(subject).to include("burger")
       expect(subject).to include("bur")
    end
  end
  
  describe [1, 5, 7] do
    it "checks inclusion value in the array" do
      expect(subject).to include(1) 
      expect(subject).to include(5) 
      expect(subject).to include(7) 
      expect(subject).to include(7, 5) 
    end
  end
  
  describe { t: 5, y: 7} do
    it "checks key or key value pair" do
      expect(subject).to include(:t) 
      expect(subject).to include(:t, :y)
      expect(subject).to include(t: 5)
    end
    
    it { is_expected.to include(:y)}
  end
end

这个的用法也很简单,有个重点就是他不看顺序的,主要是看内容物来觉得测试通过与否!

raise_error matcher

这个 Matcher 就是拿来测试喷错的结果的,没错!工程师当然要能够预期错误的结果 ( 虽然工作上大部分都没有预期到... )

如果是写在 Rails 的专案中,确实还蛮常使用到的,在某些特殊的情况需要加入 begin...rescue 时,就会写到了~

那我们还是来简单的示范一下状况!

RSpec.describe "raise error matcher" do
  
  def wrong_method 
    gggg
  end

  it "check error being raised" do
    expect { wrong_method }.to raise_error
  end
end

首先讲写法上面,记得我们之前提过,若是要执行方法等等,要记得使用 { } 来做执行的动作~

再来是你能预期这个方法会喷什麽样的错误吗?

我们先看看测试的结果:

通过了测试,但是官方希望你可以更详细的解释这是一个什麽样的 Error,所以我们只要在後方加上:

expect { wrong_method }.to raise_error(NameError)

这样就可以看到正常的 Output 了,当然你也可以在设定档里面关闭这个提醒,但还是写的仔细好一些~

甚至我们还可以自己建造错误类别来继承原本的错误类别,执行自己的错误哈哈

class CustomError < StandardError; end

it "rails himself" do
  expect { raise CustomError }.to raise_error(CustomError)
end

respond_to matcher

这个 Matcher 主要在测试一个 API 的接口所回应的方法!

也可以说成类别啦,一个类别会有的方法,以及所需的参数等等~

我们看看范例就能了解罗~我们先建造一些类别来使用!

class Burger
  def eat
   p "yummy!!!!" 
  end
  
  def discard
   p "So bad..." 
  end
  
  def buy(money)
   p "i will spend #{money} to buy this good shit!!" 
  end
end


RSpec.describe "respond_to matcher" do
  
  describe Burger do
    it "checks an object respond method" do
      expect(subject).to respond_to(:eat) 
      expect(subject).to respond_to(:eat, :discard)
      expect(subject).to respond_to(:eat, :discard, :buy)
    end
    
    it "checks method and arguments" do
        expect(subject).to respond_to(:buy).with(1).arguments 
    end  
  end
end

写起来有点多,但其实就是测试这个类别回应的公开方法而已,注意!!私有方法是没办法被 respond_to 的喔~

毕竟都已经是 private 还可以公开的回应,那好像也怪怪的!

satisfy matcher

这个 Matcher 超级好用,而且弹性超大~

不像前几个 Matcher 基本上都是 Ruby 的语法转型变成 RSpec 的语法,这个是独有的!!!

我们先看看示范:

RSpec.describe "satisfy matcher" do
  subject { 'level' }
  
  it "is a palindrome" do
    expect(subject).to satisfy { |value| value == value.reverse } 
  end
  
  it "can do something in block" do
    expect(10).to satisfy { |value| value / 2 == 5 } 
  end
  
  it "can add custom message" do
    expect(100).to satisfy("bigger than 50") do |value|
      value > 50
    end
  end
end

他就是一个只要能够在 block 里面满足条件,就可以通过测试的一个好东西!

弹性很高,可以在里面写入很多 Ruby 的语法,在测试的时候也比较不会绑手绑脚的。

客制化讯息也会在 Output 上一并出现,这个 Matcher 先推推!

compound expection

这个就是一个 expection 而且蛮无聊的,想说就也提一下好了!

简单来说就是合成你的 RSpec 语法,要 and && 或是 or || 对比上你的复数 Matcher 才能够通过~

RSpec.describe 30 do
  it "test for multiple matchers" do
    expect(subject).to be_even.and be > 25
  end
  
  describe [1, 5, 7] do
    it "can use or" do
      expect(subject.sample).to eq(1).or eq(5).or eq(7)  
    end
  end
end

就如范例所示,可以串接你的 Matcher 然後使用 and 或是 or 方法来串联!

小结

终於结束了满满的 Matcher 海,接下来就进入到一开始我最难理解的 double 以及 stub 的章节了!

也是我觉得超级好用的地方,真的能够办到很多有趣的事情!


<<:  【Day 17】Google Apps Script - API 篇 - Spreadsheet Service - 电子试算表服务介绍

>>:  Day 17 ATT&CK for ICS - Persistence(2)

[Day 23] 针对API的单元测试(三)

我们今天来针对API做更进一步的测试, 假如我们今天要取得一个使用者资料, 这个使用者的资料有 代号...

Day 29 - 回传值

虽然我们实作了好几个方法,但忘记了要处理方法回传值,在 mruby 中处理回传值也是相当简单的,因为...

CMoney第八届菁英软件工程师战斗营_Week 2

安安 过了一周我又来了 首先需要先为自己与同学鼓掌撑过第一周✌️ 第二周开始就是介面地狱 每周第一天...

卡夫卡的藏书阁【Book28】- Kafka - MirroMaker

“In man's struggle against the world, bet on the ...

Day 4【HTML + CSS】於是他开始像灵犬莱西一样到处蒐集证据

【前言】 不知道大家有没有看过 Youtube 上面一些 5~12 小时的 Coding 教学影片...