RSpec Expectation And change matcher

RSpec Expectation 被用来描述期望的输出,测试中表明“描述被测试代码行为”。在 RSpec 中,期望语句 expect 放在 it block 中。例如:

it "is in default queue" do
expect(EmailJob.new.queue_name).to eq('default')
end

那么什么是 matcher 呢?通俗解释 matcher 就是呼应 Expectation 。例如上面代码片段中,期望 ... 等于 ....
在 Rspec 中有 built it matchercustom matcher 而在这篇文章重点介绍 change 这个 built in matcher
change matcher 被用来指定代码块被执行之后导致值被改变。例如测试 ActiveJob 发送邮件队列任务,期望任务执行之后 ActionMailer 中邮件数量变化为 1

it "excutes perform" do
expect {
  perform_enqueued_jobs { job }
}.to change { ActionMailer::Base.deliveries.size }.by(1)
end

另外一个例子,ActiveJob 任务入队操作,我们期望队列中任务大小变化量为 1

it "queues the job" do
expect { job }.to change(ActiveJob::Base.queue_adapter.enqueued_jobs, :size).by(1)
end

总结有两种使用 change matcher 格式

  • expect { do_something }.to change(object, :attribute)
  • expect { do_something }.to change { object.attribute }

结合上述的两个例子,我们还发现有个 by 表示 change 方法中代码块执行之后的变化值。除了 by 其实还有两个方法, 那就是 fromto 举个例子,有一个计数器的类方法 increment 调用该方法后自增1

class Counter
class << self
  def increment
    @count ||= 0
    @count += 1
  end

  def count
    @count ||= 0
  end
end
end
require "counter"
RSpec.describe Counter, "#increment" do
  it "should increment the count" do
    expect { Counter.increment }.to change{Counter.count}.from(0).to(1)
  end
  # deliberate failure
  it "should increment the count by 2" do
    expect { Counter.increment }.to change{Counter.count}.by(2)
  end
end

执行测试之后,第一个测试用例通过,第二个不通过。

继续阅读:

0 条评论
您想说点什么吗?