如何测试 Rails 与 RSpec 中的复杂关系?

How do I test complex relationships in Rails with RSpec?

首先,这个问题可能会偏离观点,但我认为这是一个有价值的问题。我将为处理缺勤管理和跟踪的应用程序提供一个非常具体的示例。

一个Account有很多Users,一个User有很多AbsencesAccount 可以创建 PublicHolidays,在计算 Absence 使用的天数时应该忽略它。

示例:如果一个人休假一周,则使用的天数将为 5。如果其中一天是 PublicHoliday,则使用的天数将为 4。

我想实现一种方法,以便在创建 PublicHoliday 时,用于在创建日期之前创建的任何 Absences 且与 [=20] 的日期相交的天数=] 重新计算。

我当前的 RSpec 测试如下所示:

it 'triggers a recalculation of absence days on create for absences created before the date of creation of the public holiday' do
  robin = FactoryGirl.create(:robin)
  absence = FactoryGirl.create(:basic_absence, user: robin)
  expect(absence.days_used).to eq(1)
  ph = FactoryGirl.create(:public_holiday, country: "England", account: robin.account)
  expect(absence.reload.days_used).to eq(0)
end

在此测试中,phabsence 的日期相同,所以我希望它计算一天开始,然后我打算使用创建后回调来重新计算天数用过。

这是做这个测试的正确方法吗?有没有更有效的方法而不创建多个关联对象?

首先 - 最好使用 lets 而不是局部变量,其次 - 拆分你的测试,这样每个测试只测试一件事。第三:任何为测试设置上下文的东西都应该放在上下文块中(即使在那个上下文中只有一个测试)

例如,这是以标准方式重写您的规范:

let(:robin) { FactoryGirl.create(:robin) }
let(:absence) { FactoryGirl.create(:basic_absence, user: robin) }


context "with no public holidays" do
  it 'counts the absence day to be a day used' do
    expect(absence.days_used).to eq(1)
  end
end

context "with a public holiday for the absence" do
  before do
    FactoryGirl.create(:public_holiday, country: "England", account: robin.account)
  end
  it 'does not consider the absence day to be a day used' do
    expect(absence.days_used).to eq(0)
  end
end