collection_select没有使用FactoryGirl在Capybara的rspec测试中填充

时间:2012-08-26 15:42:14

标签: ruby-on-rails rspec capybara factory-bot rspec-rails

我正在尝试使用capybara测试从collection_select元素中选择一个值,并且由于某种原因,在运行rspec时填充collection_select的数据不存在,但是在运行rails应用程序时。

示例:

html定义

<%= form_for(@notification) do |f| %>

    <%= f.label :device, "Select a Device to notify:" %>
    <%= f.collection_select :device_id, Device.all, :id, :device_guid, prompt: true %>

<% end %>

rspec定义

describe "NotificationPages" do

  subject { page }

  let(:device) { FactoryGirl.create(:device) }
  let(:notification) { FactoryGirl.create(:notification, device: device) }

  describe "new notification" do
    before { visit new_notification_path }

    let(:submit) { "Create Notification" }

    describe "with valid information" do
      before do
        select(device.device_guid, from: 'notification_device_id')
        fill_in "Message", with: "I am notifying you."
      end

      it "should create a notification" do
        expect { click_button submit }.to change(Notification, :count).by(1)
      end
    end
  end
end

运行测试时,我收到以下错误消息:

Capybara::ElementNotFound: cannot select option, no option with text 'device_guid' in select box 'notification_device_id'

看起来,collection_select中的Device.all调用在测试期间没有返回任何内容。关于我做错了什么想法?

谢谢, 佩里

2 个答案:

答案 0 :(得分:4)

强制早期评估let的更好方法是使用!,如下所示:

let!(:device) { FactoryGirl.create(:device) }

这样你就不需要额外的代码。

答案 1 :(得分:1)

当您访问new_notification_path时,数据库中没有设备。发生这种情况是因为let是惰性求值的,因此它定义的方法在您第一次调用它时被调用,在您的测试中,只有在执行select(device.device_guid ...)语句时才会调用它。

要确保在访问路径之前创建设备,您只需在前一个块中调用“设备”即可。

before do
  device
  visit new_notification_path
end