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'

collection_selectのDevice.all呼び出しは、テスト中に何も返さないようです。私が間違っていることについて何か考えはありますか?

ありがとう、ペリー

4

2 に答える 2

4

letの早期評価を強制するためのより良い方法は、次のように!を使用することです。

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

そうすれば、余分なコード行は必要ありません。

于 2012-12-14T05:28:10.453 に答える
1

new_notification_pathにアクセスした時点では、データベースにデバイスがありません。これは、letが遅延評価されるために発生します。そのため、letが定義するメソッドは、最初に呼び出すときに呼び出されます。これは、テストでは、select(device.device_guid ...)ステートメントを実行したときにのみ発生します。

パスにアクセスする前にデバイスが作成されていることを確認するには、beforeブロックで「device」を呼び出すだけです。

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