Ruby on rails 删除rspec中的测试-更改(型号::计数)失败-为什么需要重新加载?
TLDR:App.count需要重新加载才能查看创建的记录。为什么? 我发现很多关于测试DELETE方法的参考资料如下:Ruby on rails 删除rspec中的测试-更改(型号::计数)失败-为什么需要重新加载?,ruby-on-rails,ruby,testing,rspec,Ruby On Rails,Ruby,Testing,Rspec,TLDR:App.count需要重新加载才能查看创建的记录。为什么? 我发现很多关于测试DELETE方法的参考资料如下: expect { delete_request }.to change(App, :count).by(-1) 这是有道理的,并且在一些类似的场景中也有效。然而,当测试一个不应该工作的删除时,我发现了一个问题,比如当没有用户登录时 我从这里开始,用两种方法来测试相同的东西: require 'rails_helper' RSpec.describe V1::AppsCon
expect { delete_request }.to change(App, :count).by(-1)
这是有道理的,并且在一些类似的场景中也有效。然而,当测试一个不应该工作的删除时,我发现了一个问题,比如当没有用户登录时
我从这里开始,用两种方法来测试相同的东西:
require 'rails_helper'
RSpec.describe V1::AppsController, type: :controller do
let(:user) { create(:user) }
let(:app) { create(:app, account: user.account) }
describe 'DELETE destroy when you are not logged in' do
let(:delete_request) { delete :destroy, id: app, format: :json }
it 'does not delete the app (.count)' do
expect { delete_request }.not_to change(App, :count)
end
it 'does not delete the app (.exists?)' do
delete_request
expect(App.exists?(app.id)).to eq(true)
end
end
end
这就是rspec所说的:
V1::AppsController
DELETE destroy when you are not logged in
does not delete the app (.count) (FAILED - 1)
does not delete the app (.exists?)
Failures:
1) V1::AppsController DELETE destroy when you are not logged in does not delete the app (.count)
Failure/Error: expect { delete_request }.not_to change(App, :count)
expected #count not to have changed, but did change from 0 to 1
# ./spec/controllers/v1/delete_test_1.rb:11:in `block (3 levels) in <top (required)>'
2 examples, 1 failure
现在rspec很高兴:
V1::AppsController
DELETE destroy when you are not logged in
App.count is 0 (after create(:app))
App.count is 1 (after reload)
App.count is 1 (after request)
does not delete the app (.count)
does not delete the app (.exists?)
2 examples, 0 failures
因此,我决定坚持使用exists?
方法。但另一个(可能更大的)担忧是,我在互联网站上找到的所有测试样本都是为了测试创建记录,比如expect{create_request}.to change(App,:count)。by(1)
可能是误报,如果他们看到的结果与我相同,并且假设创建的记录实际上是一个缓存工件
那么,你知道为什么App.count需要重新加载才能看到当前值吗 这是因为当ruby调用
delete\u请求
方法时,它调用app
方法,并创建一个app
要测试这一点,请在调用expect
rspec方法之前创建应用程序:
it 'does not delete the app (.count)' do
app #creates the app
expect { delete_request }.not_to change(App, :count)
end
请看一下let
的文档:
使用let定义已记忆的辅助对象方法。该值将被缓存
跨同一示例中的多个调用,但不跨示例
注意,let是惰性计算的:直到第一个
调用它定义的方法的时间。你可以用let!逼迫
方法在每个示例之前的调用
完美,罗德里戈!我试着在expect之前提到
app
,并使用let代码>,两种方法都解决了问题。感谢您的修复和参考。演示了问题以及两种解决方案。
it 'does not delete the app (.count)' do
app #creates the app
expect { delete_request }.not_to change(App, :count)
end