Ruby on rails Rails-Rspec/Capybara报告失败,除非添加睡眠

Ruby on rails Rails-Rspec/Capybara报告失败,除非添加睡眠,ruby-on-rails,rspec,capybara,Ruby On Rails,Rspec,Capybara,我有一个页面,登录用户可以通过提交一个ajax请求来设置一个喜爱的项目,该请求调用以下控制器方法: def create item = Item.find(params[:id]) if params[:commit] == 'save' item.unhide!(current_user) if item.is_hidden_by?(current_user) item.save_as_favourite_for!(current_user)

我有一个页面,登录用户可以通过提交一个ajax请求来设置一个喜爱的项目,该请求调用以下控制器方法:

def create
    item = Item.find(params[:id])
    if params[:commit] == 'save'
        item.unhide!(current_user) if item.is_hidden_by?(current_user)
        item.save_as_favourite_for!(current_user)
    else
        item.remove_as_favourite!(current_user) if item.is_favourite_of?(current_user)
        item.hide_for!(current_user)
    end
    respond_to do |format|
     format.html { redirect_back_or items_path }
     format.js {render "create", locals: {item: item, index: params[:index].to_i || nil, page:params[:page]} }
    end
end
这一切都按预期进行,但我有一个用于测试前端功能的请求规范:

describe "saving items", js: true do

    let!(:current_user) {FactoryGirl.create(:user, email: "user@example.com", active: true)}

    let!(:favourite_item) {FactoryGirl.create(:item)}
    before { sign_in current_user }

    describe "when saving a item" do

        it "should save the user against the item" do

            expect do

                click_button "save"
                # sleep(0.02)

            end.to change(favourite_item.savers, :count).by(1)

        end
    end
end
注意注释掉的sleep(0.02)语句。如果这个语句被注释掉,测试(几乎)总是失败,但是如果我包括调用,并立即结束控制台中断,那么每次测试都会通过。(任何更多的时间延迟都会失败)


有没有更好的方法在没有解决方法的情况下编写此测试?为什么它会在没有延迟的情况下失败?

您可以使用dsl设置等待时间

using_wait_time 3 do
  expect do
    click_button "save"
  end.to change(favourite_item.savers, :count).by(1)
end

如果您使用Rspec匹配器,JS测试的默认等待时间为2秒,而您不适合此测试


如果您删除
js:true
,它可能也会通过,除非您确实需要js驱动程序进行测试。

这与在块中添加睡眠有什么区别?不幸的是,在这种情况下,它似乎无论如何都不起作用。我将检查我的测试,因为我可能对js:true很开放,但我确信在大多数情况下js是起作用的。