我刚刚升级到 Rails 5。在我的规范中,我有以下内容
期望(模型).to receive(:update).with(foo: 'bar')
但是,由于 params
不再扩展 Hash
而现在是 ActionController::Parameters
规范失败了,因为 with()
期待一个散列,但它实际上是 ActionController::Parameters
是否有更好的方法在 Rspec 中做同样的事情,例如不同的方法 with_hash
?
我可以使用
解决这个问题expect(model).to receive(:update).with(hash_including(foo: 'bar'))
但这只是检查参数是否包含该散列,而不是检查是否完全匹配。
最佳答案
你可以这样做:
params = ActionController::Parameters.new(foo: 'bar')
expect(model).to receive(:update).with(params)
但是它仍然有味道 - 您应该测试应用程序的行为 - 而不是它如何工作。
expect {
patch model_path(model), params: { foo: 'bar' }
model.reload
}.to change(model, :foo).to('bar')
这就是我测试 Controller 集成的方式:
require 'rails_helper'
RSpec.describe "Things", type: :request do
describe "PATCH /things/:id" do
let!(:thing) { create(:thing) }
let(:action) do
patch things_path(thing), params: { thing: attributes }
end
context "with invalid params" do
let(:attributes) { { name: '' } }
it "does not alter the thing" do
expect do
action
thing.reload
end.to_not change(thing, :name)
expect(response).to have_status :bad_entity
end
end
context "with valid params" do
let(:attributes) { { name: 'Foo' } }
it "updates the thing" do
expect do
action
thing.reload
end.to change(thing, :name).to('Foo')
expect(response).to be_successful
end
end
end
end
在规范中接触数据库是天生的坏事吗?
没有。当您测试 Controller 之类的东西时,最准确的测试方法是驱动整个堆栈。如果我们在这种情况下删除了 @thing.update
,我们可能会错过数据库驱动程序抛出的错误,因为我们使用了错误的 SQL 语法。
例如,如果您要在模型上测试作用域,那么将数据库 stub 的规范将给您带来很小的值(value)甚至没有值(value)。
Stubbing 可能会为您提供一个快速的测试套件,但由于紧密耦合,该套件非常脆弱,并且会让大量错误从裂缝中溜走。
关于ruby-on-rails - Rails 5 Rspec 接收 ActionController::Params,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39702947/