ruby-on-rails 如何循环具有不同期望的rspecs

wqsoz72f  于 2022-11-19  发布在  Ruby
关注(0)|答案(1)|浏览(142)

我有三个模型规范,它们的代码相似,但预期的数值结果稍有不同。我没有重复代码三次,而是尝试用一种干燥的方式来完成。
代码如下:

tests = [
  {test_name: "this-year", arrival_date: 2.days.ago,    ytd: 1, ly: 0},
  {test_name: "last-year", arrival_date: 14.months.ago, ytd: 0, ly: 1},
  {test_name: "very old",  arrival_date: 3.years.ago,   ytd: 0, ly: 0},
]

tests.each do |t|
  it "increments #{t[:test_name]} order correctly" do
    expect{
      order = create(:order, buyer: @bs.buyer, seller: @bs.seller, arrival_date: t[:arrival_date])
      @bs.reload
    }.to change{ @bs.orders_count }.from(0).to(1)
    .and change{ @bs.orders_count_ytd }.from(0).to(t[:ytd])
    .and change{ @bs.orders_count_ly }.from(0).to(t[:ly])
  end
end

对我来说,这个设置很有意义--它允许我们很容易地看到测试之间的区别,并且它消除了冗余代码。
但是,这会引发错误:

[Test 1]: expected `@bs.orders_count_ly` to have changed from 0 to 0, but did not change
[Test 2]: expected `@bs.orders_count_ytd` to have changed from 0 to 0, but did not change
[Test 3]: expected `@bs.orders_count_ytd` to have changed from 0 to 0, but did not change
            ...and:
          expected `@bs.orders_count_ly` to have changed from 0 to 0, but did not change

我所知道的唯一的解决方案是添加丑陋的if/then类型语句来改变基于测试的期望,但这似乎使这种方法的优点(简洁和清晰)变得没有意义。有没有一种优雅的方式来完成这项工作,尊重既定的模式?

bvpmtnay

bvpmtnay1#

问题是RSpec不喜欢...to change(...).from(0).to(0)
也许纯粹主义者会说每个it块应该只有一个期望,但无论如何我会这样做:

tests = [
  {test_name: "this-year", arrival_date: 2.days.ago,    ytd: 1, ly: 0},
  {test_name: "last-year", arrival_date: 14.months.ago, ytd: 0, ly: 1},
  {test_name: "very old",  arrival_date: 3.years.ago,   ytd: 0, ly: 0},
]

tests.each do |t|
  it "increments #{t[:test_name]} order correctly" do
    bs = create(:order, buyer: @bs.buyer, seller: @bs.seller, arrival_date: t[:arrival_date])
    expect( bs.orders_count ).to eq 1
    expect( bs.orders_count_ytd )to eq t[:ytd]
    expect( bs.orders_count_ly).to eq t[:ly]
  end
end

(not我知道@bs的来源,但我假设它的代码早于您所展示的代码)

相关问题