1

我正在尝试使用 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'

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

谢谢,佩里

4

2 回答 2

4

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

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

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

于 2012-12-14T05:28:10.453 回答
1

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

为确保在访问路径之前创建设备,您可以在 before 块中调用“设备”。

before do
  device
  visit new_notification_path
end
于 2012-08-26T16:10:51.960 回答