Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 删除rspec中的测试-更改(型号::计数)失败-为什么需要重新加载?_Ruby On Rails_Ruby_Testing_Rspec - Fatal编程技术网

Ruby on rails 删除rspec中的测试-更改(型号::计数)失败-为什么需要重新加载?

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

TLDR:App.count需要重新加载才能查看创建的记录。为什么?

我发现很多关于测试DELETE方法的参考资料如下:

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