3

我是 Rails 和 TDD 的新手。我目前正在使用 Capybara 和 RSpec 测试我的页面。

我在主页 (root_path) 上有一个表单,它通过 post 提交给 Linkage 控制器:

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

它进入Linkages 控制器的创建操作,理想情况下应该使用 AJAX (format.js) 更改 root_path 的数据:

  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(如下)中为其编写测试时,它失败了,因为它重定向回 root_path(format.html),而不是渲染 format.js 块中指定的页面(更改 root_path 中的数据)。

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

,然后 Capybara 最终为我呈现正确的页面,但如果我调用save_and_open_page 它,那么我会看到所有转义的 javascript 和错误呈现的 HTML,所以我无法测试类似have_selector().

我的问题是为什么会这样?是因为 Capybara 使用 GET 而不是 POST 并且即使单击链接也不一定会在控制器内部调用正确的格式?

PS 使用 format.js(排序)切换 format.html 并不能解决问题 - format.html 被调用。

4

2 回答 2

2

AFAIK Capybara 适合 POST。:js => true如果您使用的是 capybara-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 回答