首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rspec::与接收者和消息与块匹配的“更改”方法

Rspec::与接收者和消息与块匹配的“更改”方法
EN

Stack Overflow用户
提问于 2015-01-26 17:12:39
回答 1查看 546关注 0票数 2

我在试着删除一个关联。所涉及的两个模型是UserCancellation

代码语言:javascript
复制
    class Cancellation < Active Record::Base
      belongs_to :taker, class_name: "User"
    end

    class User < ActiveRecord::Base
      has_many :taken_cancellations, class_name: "Cancellation", foreign_key: :taker_id
    end

在我的测试中,我得到了以下代码:

代码语言:javascript
复制
describe "Admin Calendar" do
  subject { page } 

  let!(:user) { FactoryGirl.create(:user, name: "Taker User") }
  let(:cancellation) { FactoryGirl.create(:cancellation, start_at: 2.days.from_now, taker: user) }

  before do
    sign_in admin
    visit edit_admin_cancellation_path cancellation
  end

  #...

  describe "Edit Page" do
    it 'Making it available' do
      expect { click_link "Make it available" }.to change(cancellation.reload, :taker).from(user).to nil
    end
  end
end

click_link 'Make it available将在控制器中触发user.taken_cancellations.delete @cancellation

此错误导致测试失败:

代码语言:javascript
复制
taker should have been changed to nil, but is now #<User id: 1, name: "Taker User"...

来自let方法指南:https://relishapp.com/rspec/rspec-core/v/2-6/docs/helper-methods/let-and-let

该值将被缓存在同一个示例中的多个调用中,而不是跨示例缓存。

在我看来,change方法似乎是在操作之后创建一个新的cancellation,而不是查看回忆录。我没想到会有这种行为。

测试在使用块时通过,如下所示:

代码语言:javascript
复制
expect { click_link "Make it available" }.to change { cancellation.reload.taker }.from(user).to nil

有人能解释我说得对吗?为什么会有这些不同的行为?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-28 04:16:47

在第一种形式中,对cancellation.reload进行一次计算,结果对象在调用click_link方法之前和之后发送消息taker。换句话说,在调用cancellation之后,不会重新加载click_link对象。

在第二种形式中,在调用cancellation.reload.taker之前和之后对click_link进行完整的评估,因此reload有机会在数据库更新之后生效。

但是请注意,根据您的配置,处理click_link结果的服务器可能在一个单独的线程中执行,因此在任何情况下,数据库的更新和测试断言之间都存在竞争条件。

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

https://stackoverflow.com/questions/28155136

复制
相关文章

相似问题

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