具有相同代码的两个测试之间的Rspec结果不一致



我有一个模型规范,它抛出了一个意外错误(没有正确构建对象(。当我将相同的代码移到以前的测试中时,它会顺利运行。

以下是有问题的预期:

expect(title.full_title.length).to be <= 140

当将线路添加到第一次测试时,它通过了,而第二次测试失败:

describe "generates a title" do
let(:collection) { FactoryBot.create(:collection) }
let(:items) { FactoryBot.create_list(:item, 10, collection: collection, chosen: true) }
let(:title) { Title.create_title(collection) }
context "happy path" do
it "assigns keywords by score" do
array = []
items.each do |i|
array << [i.search.term, i.search.score]
end
array.sort! { |a, b| a[1] <=> b[1] }
split_title = title.full_title.split(', ')
remaining_chars = 140
i = 0
split_title.each do |s|
if remaining_chars - s.length >= 0
expect(s).to eq(array[i][0])
i +=  1
remaining_chars -= s.length
end
expect(title.full_title.length).to be <= 140
end
end
it "does not exceed 140 characters" do
expect(title.full_title.length).to be <= 140
end
end

这是错误消息,它没有创建对象:

1) Title generates a title happy path does not exceed 140 characters
Failure/Error: remaining_chars = 140 - keywords[0].length
NoMethodError:
undefined method `length' for nil:NilClass

TIA!

这是一个很长的机会,但如果我今天幸运的话,让我们试试。

猜测:Title.full_title实现(您没有共享(在某种程度上取决于与用于初始化Title对象的集合相关的Item的存在。

如果这个假设是正确的,不同的行为来自于let的懒惰本质。

在第一个it中,您实际上调用了items(例如items.each(,因此会评估let(:items),创建DB中的行,并且title.full_title不会返回nil

有几种可能的多种方法可以修复它:

  1. 改进full_title的实现,使其始终返回字符串
  2. 在第二种情况下之前调用items

it "does not exceed 140 characters" do items expect(title.full_title.length).to be <= 140 end

  1. 使用立即评估的let!(:items)(不懒惰(

最新更新