3

Rails と TDD は初めてです。私は現在、自分のページを Capybara と RSpec でテストすることに固執しています。

リンケージコントローラーへの投稿を介して送信するホームページ(root_path)にフォームがあります:

<%= form_for @link, url: linkages_path, method: :post,  remote: true do |f| %>
    <%= f.labels/text_fields... %>
    <%= f.submit "Add Link" %>
<%  end %>

Linkages controllerの create アクションに到達し、理想的には root_path のデータを AJAX (format.js) で変更する必要があります。

  def create
    @link = Link.new(params[:link])
    if @link.save and current_user.linkages.build(link_id: @link.id).save
      flash.now[:success] = "Link to \"#{@link.content}\" was successfully added!"
      respond_to do |format|
        format.html { redirect root_path }
        format.js do
            @user_linkage = current_user.linkages
            render 'users/user_linkage.js.erb'
        end
      end
    else
      flash.now[:error] = "..."
      error...
    end
  end

成功すると、js ファイル users/user_linkage.js.erb がレンダリングされます。これは次のとおりです (root_path の userLinkage div を変更するだけです)。

$('#flash').html("<%= escape_javascript(raw(flash_display)) %>");
$('#userLinkage').html("<%= escape_javascript(render partial: 'users/user_linkage_items',
                                             locals: {user_linkage: @user_linkage }) %>");

また、Chrome/Firefox/IE/Opera で完全に動作します。ただし、Capybara (以下) でテストを作成すると、format.js ブロックで指定されたページをレンダリングする (root_path のデータを変更する) のではなく、root_path (format.html) にリダイレクトされるため失敗します。

describe "test" do

    let(:link){'some link'}
    let(:text){'some text'}

    before do
        visit root_path
        fill_in 'Text', with: link
        fill_in 'Link', with: text
    end

    it "should work" do

        expect do
            click_button 'Add Link'
        end.to change(Link, :count).by(1)
        sleep(5)
        should have_content(text)                 # works until here (root_path has same info)
        should have_selector('div.alert-success') # fails on this line(flash message)
    end
end

したがって、Capybara は GET リクエストしか実行できず、私のフォームは POST にあることはわかっていますが、ユーザー シミュレーションに関しては、そのようなことは無関係 (?) である必要があります。

成功時にフォーマットを format.html/format.js から次のように変更すると:

  respond_to do |format|
    format.all do
        @user_linkage = current_user.linkages
        render 'users/user_linkage.js.erb'
    end
  end

、その後、カピバラは最終的に正しいページをレンダリングしますが、それを呼び出すとsave_and_open_page 、エスケープされたすべての JavaScript と誤ってレンダリングされた HTML が表示されるため、have_selector().

私の質問は、なぜそれが起こっているのですか?カピバラが POST の代わりに GET を使用し、リンクをクリックしても必ずしもコントローラー内で正しい形式を呼び出さないためですか?

PS format.js で format.html を切り替える (順序付け) ことはできません。format.html が呼び出されます。

4

2 に答える 2

2

私の知る限り、カピバラは POST で問題ありません。:js => truecapybara-webkit を使用している場合は追加します。あなたのjsで必要なもの.html_safe

$('#userLinkage').html("<%= escape_javascript(render partial: 'users/user_linkage_items',
                                         locals: {user_linkage: @user_linkage }).html_safe %>");

これも:

current_user.linkages.build(link_id: @link.id).save

次のように変更できます。

current_user.linkages.create(link_id: @link.id)

また、一定のインデント スキームに従います (2 つのスペースが一般的に使用されます)。

于 2012-10-08T17:45:02.490 に答える
1

テストに追加する必要がありjs: trueます。

it "should work", js: true do
于 2015-11-24T01:19:27.973 に答える