对于rspec匹配器中的模型计数,“nil不是符号”

时间:2012-11-05 20:33:38

标签: ruby-on-rails ruby-on-rails-3 rspec tdd capybara

我正在尝试编写集成测试,如果用户点击某个按钮,它会在数据库中创建一条新记录(CheckPrice模型)。

当我尝试运行测试时,我遇到了错误nil is not a symbol

require 'spec_helper'

describe 'CheckPrice', type: :request, js: true  do
  it "should create a new CheckPrice record when user clicks Check Price on topic page" do
    city = create :city
    hotel = create :hotel
    affiliate_link = create :affiliate_link

    visit '/hotel-bilboa-hotel'
    sleep 2
    click_button "Check Prices"
    response.should change(CheckPrice.count).by(1)
  end
end

单击“检查价格”时,会有一个事件侦听器触发checkprices_controller中的新方法。

错误似乎发生在最后一行response.should change(CheckPrice.count).by(1)。看起来该方法无法识别模型CheckPrice。如何引用CheckPrice表?

感谢。

4 个答案:

答案 0 :(得分:16)

我认为你不能在响应对象上使用这样的change匹配器。试试这个:

expect {
  click_button "Check Prices"
}.to change{ CheckPrice.count }.by(1)

这也使IMO更具语义感。

有关更多示例,请参阅this cheat sheet

答案 1 :(得分:15)

除了语义之外,回答原始问题(获得“nil不是符号”)并帮助其他可能像我一样落在这里的人:确保使用大括号{}而不是括号()。

所以(正确)

response.should change{CheckPrice.count}.by(1)
response.should change(CheckPrice, :count).by(1)

代替(不会起作用,上述2的混合)

response.should change(CheckPrice.count).by(1)

修改

recommended expect syntax

的答案相同

所以(正确)

expect{response}.to change{CheckPrice.count}.by(1)
expect{response}.to change(CheckPrice, :count).by(1)

代替(不会起作用,上述2的混合)

expect{response}.to change(CheckPrice.count).by(1)

答案 2 :(得分:1)

另一种方法是:

expect do
    click_button "Check Prices"
end.to change(CheckPrice, :count).by(1)

这表明countCheckPrice方法的输出应该是应该改变的。当两个参数传递给change时,假定一个是接收者,另一个是要发送的符号。

答案 3 :(得分:0)

我遇到了同样的问题,正如其他答案所说的那样,在这种情况下,方法expectchange都需要一个块作为参数。

因此,在rails中,您可以使用{}或do end语法。