我刚刚升级到Rails 5.在我的规格中,我有以下
expect(model).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是否包含该哈希值,而不是检查完全匹配。
答案 0 :(得分:5)
你可以这样做:
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')
这就是我测试控制器集成的方法:
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
没有。当您测试控制器之类的东西时,最准确的测试方法是驱动整个堆栈。如果我们在这种情况下已经删除了@thing.update
,那么我们可能会错过,例如数据库驱动程序因为我们使用错误的SQL语法而引发错误。
如果您是在模型上测试范围,那么存储数据库的规范将为您提供很少甚至没有价值。
Stubbing可以为您提供一个快速测试套件,由于紧密耦合而非常脆弱,并且可以让大量的虫子穿过裂缝。
答案 1 :(得分:2)
我通过在spec / rails_helper.rb
中创建来处理此问题def strong_params(wimpy_params)
ActionController::Parameters.new(wimpy_params).permit!
end
然后在特定测试中,您可以说:
expect(model).to receive(:update).with(strong_params foo: 'bar')
它与你已经做过的事情没什么不同,但它使这个额外调用的尴尬必要性在语义上更有意义。
答案 2 :(得分:1)
但是,如果您仍然想要使用它们,作为更复杂情况的简单黑客(例如,如果while(qr.next()){
salesTable = qr.get(tablenum(SalesTable));
}
使用expect
),您可以尝试使用以下内容:
a_hash_including