RSpec - 除非从撬点调用局部变量,否则测试失败

RSpec - failing test unless local variable is called from pry point

我有以下代码:

## teams_controller.rb

def destroy
  ActiveRecord::Base.transaction do
    team_admins = team.team_admins
    binding.pry
    team.destroy!
    team_admins.each(&:update_team_admin_role_if_needed!)
  end

  respond_with_200(team, serializer: V1::User::Management::TeamSerializer)
end

以及确保上述代码最后一行触发的相应规范:

## teams_controller_spec.rb

it 'demotes team admins to employees when needed' do
  team_admin_account = create(:account)
  admin_team_membership = create(:team_membership, team: @team, admin: true, account: team_admin_account)
  team_admin_account.update!(role: Role.team_admin)

  expect { process_destroy(team_id: @team.slug) }
    .to change { team_admin_account.reload.role }
    .from(Role.team_admin)
    .to(Role.employee)
end

当我在我的应用程序中使用上面的代码时,它按预期工作,但是规范失败了,因为帐户显然从未更新过它们的角色:

 expected `team_admin_account.reload.role` to have changed from #<Role id: 4, add_to_first_user_in_organisation: false, title: "Team admin", created_at: "2020-01-03 09:04:28", updated_at: "2020-01-03 09:04:28", management: false, cms_access: false> to #<Role id: 3, add_to_first_user_in_organisation: false, title: "Employee", created_at: "2020-01-03 09:04:28", updated_at: "2020-01-03 09:04:28", management: false, cms_access: false>, but did not change

当我在规范中找到撬动点并立即退出时,规范失败了。没有撬点时也是如此。

然而,当我在撬点输入 team_admins(returns 我在我的规范中创建的那个 team_admin)然后退出规范时,规范通过并且该帐户已更新其角色。

有人知道为什么手动调用 team_admins 让我的规范通过吗?

提前致谢

编辑:

代码的以下更改也使规范通过:

def destroy
  ActiveRecord::Base.transaction do
    team_admins = team.team_admins
    puts team_admins                        ## <---- Adding this makes the spec pass
    team.destroy!
    team_admins.each(&:update_team_admin_role_if_needed!)
  end

  respond_with_200(team, serializer: V1::User::Management::TeamSerializer)
end

team_admins 是来自 team 的 AssociationRelation。这不会执行查询直到被引用,例如 eachputs.

在调用 team_admins.each 之前调用

team.destroy!。因此,当 team_admins.each 执行时,不再有 team,因此也就没有 team_admins。您应该能够通过观察 logs/test.log 并查看查询及其执行时间来验证这一点。

恭喜,您发现了一个错误。在销毁 team.

之前执行 team_admins.each