【问题标题】:RSpec check if method has been calledRSpec 检查方法是否被调用
【发布时间】:2021-09-12 19:22:50
【问题描述】:

我有一个AccountsController 和一个destroy 操作。我想测试帐户是否被删除以及subscription 是否被取消。

AccountsController

def destroy
  Current.account.subscription&.cancel_now!
  Current.account.destroy
end

RSpec

describe "#destroy" do
  let(:account) { create(:account) }
  
  it "deletes the account and cancels the subscription" do
    allow(account).to receive(:subscription)
    expect do
      delete accounts_path
    end.to change(Account, :count).by(-1)

    expect(account.subscription).to have_received(:cancel_now!)
  end
end

但是上面的测试没有通过。它说,

(nil).cancel_now!
expected: 1 time with any arguments
received: 0 times with any arguments

因为account.subscription 返回nil 它显示了这一点。如何修复此测试?

【问题讨论】:

  • 您的意思是expect to have_received?不确定allow to have_received 是否会生成此消息。
  • 您会收到此消息,因为您的控制器中的 Current.account 与您的规范中的 let(:account) 没有任何关系。您对一件事设定期望,但使用另一件事。

标签: ruby-on-rails ruby rspec rspec-rails


【解决方案1】:

需要将控制器上下文中的账户实体替换为来自测试的账户

可能是

describe "#destroy" do
  let(:account) { create(:account) }
  
  it "deletes the account and cancels the subscription" do
    allow(Current).to receive(:account).and_return(account)
    # if the subscription does not exist in the context of the account  
    # then you should stub or create it...
    expect do
      delete accounts_path
    end.to change(Account, :count).by(-1)

    expect(account.subscription).to have_received(:cancel_now!)
  end
end

关于订阅

expect(account).to receive(:subscription).and_return(instance_double(Subscription))
# or
receive(:subscription).and_return(double('some subscription'))
# or
create(:subscription, account: account)
# or
account.subscription = create(:subscription)
# or other options ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    • 1970-01-01
    • 1970-01-01
    • 2020-07-28
    • 2014-02-11
    • 1970-01-01
    相关资源
    最近更新 更多