首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RSpec没有看到对ActiveRecord对象的“更改(对象,:消息)”语法的更改

RSpec没有看到对ActiveRecord对象的“更改(对象,:消息)”语法的更改
EN

Stack Overflow用户
提问于 2017-07-24 07:44:42
回答 1查看 1.7K关注 0票数 3

我有三个模特:

  • User
  • Company
  • Commitment

CommitmentUsersCompanies的HABTM连接表(也就是说,当User加入Company时,它会创建一个新的Commitment)。它还有几个额外的列/属性:

  • admin (用户是否拥有该公司的管理权限?)
  • confirmed_by_admin (公司管理员是否确认了该用户加入该公司的请求?)
  • confirmed_by_member (用户本人是否已经确认了加入该公司的邀请?)

我还定义了一种方便的方法,可以快速确定是否完全确认了承诺:

代码语言:javascript
复制
class Commitment < ApplicationRecord
  def confirmed?
    confirmed_by_admin? && confirmed_by_member?
  end
end

现在我正在编写一个请求规范,但出于某种原因,change匹配器只处理它的两个语法中的一个:

代码语言:javascript
复制
let :carol   { FactoryGirl.create(:user) }
let :company { FactoryGirl.create(:company) }

it 'confirms invitation to join company' do
  # Initialize unconfirmed commitment
  FactoryGirl.create(:commitment, user: carol,
                                  company: company,
                                  confirmed_by_admin: true)

  expect do
    patch commitment_path(carol.commitments.first),
          params: { commitment: { confirmed_by_member: true } }

  # for the following syntaxes, ------------------------------------------------
  # this works:
  end.to change { carol.commitments.first.confirmed?) }.from(false).to(true)
  # and this fails:
  end.to change(carol.commitments.first, :confirmed?).from(false).to(true)
  # ----------------------------------------------------------------------------

end

在对更改进行carol.commitments.first测试时,RSpec似乎没有被重新加载--我得到了以下测试输出:

代码语言:javascript
复制
Failure/Error:
  expect do
    patch commitment_path(carol.commitments.first),
          params: { commitment: { confirmed_by_member: true } }
  end.to change(Commitment.find_by(user: carol, company: company), :confirmed?).from(false).to(true)

  expected #confirmed? to have changed from false to true, but did not change
# ./spec/requests/commitments_spec.rb:69:in `block (3 levels) in <top (required)>'

怎么回事?显然,我可以坚持使用卷曲大括号/块语法,但我想了解为什么其中一种能工作,而另一种则不行。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-24 09:36:55

在检查文档并试用一个复制您的场景的新rails项目时,我相信失败的原因是

  • .change的“块”形式被运行了两次(“在”之前“”和“在”expect块之后),不管该块的内部是什么: .change{ carol.commitments.first.confirmed? }
  • .change的“方法”形式是为第一个参数运行一次:carol.commitments.first,而对于第二个参数:confirmed?运行两次。但是,这方面的问题是,规范文件中此时的carol.commitments.first与实际在commitments_controller#update中更新的对象没有共享相同的内存空间(很可能该对象名为@commitment)。尽管它们是相同的Commitment记录,但它们是单独的实例,而另一个实例的属性值在另一个实例更改时不会自动更改。

请考虑下面的示例,其中演示了此“方法”表单工作的场景:

代码语言:javascript
复制
it 'sometest' do
  commitment = FactoryGirl.create(:commitment, user: carol,
                                  company: company,
                                  confirmed_by_admin: true)
  expect do
    # this commitment object is exactly the same object passed in the `change` below
    commitment.confirmed_by_member = true
  end.to change(commitment, :confirmed?).from(false).to(true)
end

免责声明:这是未经验证的,但因为它太复杂,我写评论(所有的样本测试代码),我写在这里作为一个答案。如果有谁知道得更好,请告诉我。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45274875

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档