2

我正在编写一个请求规范,以测试will_paginate是否正常工作,但我遇到了一些问题。首先,这是我的规范的精简版本:

require 'spec_helper'

describe "Articles" do

  subject { page }

  describe "index page" do

    let(:user) { FactoryGirl.create(:user) }

    before { visit news_path }

    describe "pagination" do

      before(:all) { 31.times { FactoryGirl.create(:article, user: user) } }
      after(:all) { Article.delete_all; User.delete_all }

      let(:first_page)  { Article.paginate(page: 1) }
      let(:second_page) { Article.paginate(page: 2) }

      it "should not list the second page of articles" do
        second_page.each do |article|
          page.should_not have_selector('li', text: article.title)
        end
      end
    end
  end
end

如您所见,有一个测试可确保在用户访问文章索引页面时不显示文章的第二页。此测试失败:

1) Articles index page pagination should not list the second page of articles
   Failure/Error: page.should_not have_selector('li', text: article.title)
   expected css "li" with text "Article number 1" not to return anything

我不明白为什么这会失败。当我在开发环境中手动创建 31 篇文章并在浏览器中查看时,分页工作正常,但是当我切换到测试环境时,规范失败。

文章型号:

class Article < ActiveRecord::Base
  attr_accessible :body, :title
  belongs_to :user

  validates :user_id, presence: true

  default_scope order: 'created_at DESC'
end

文章工厂如下所示:

FactoryGirl.define do
  factory :article do
    sequence(:title)  { |n| "Article number #{n}" }
    body "This is the body"
    user
  end
end
4

1 回答 1

4

令人难以置信的是,解决方案是执行以下操作;

改变:

before(:all) { 31.times { FactoryGirl.create(:article, user: user) } }

至:

before do
  31.times { FactoryGirl.create(:article, user: user) }
  visit news_path
end

我在这里学到了两件事:

  1. before块不能以目标为目标(:all),否则测试失败
  2. 在创建工厂之后,我需要visit news_path在 before 块内显式运行,否则水豚的页面对象将不是我期望的那样

所以,为了说明:

这不起作用:

# fails because it targets (:all)
before(:all) do
  31.times { FactoryGirl.create(:article, user: user) }
  visit news_path
end

这也不会:

# fails because we are visiting the news path before the objects exist
before do
  visit news_path
  31.times { FactoryGirl.create(:article, user: user) }
end

它需要是这样的:

# not targeting (:all) and only visiting news path after creation of the objects
before do
  31.times { FactoryGirl.create(:article, user: user) }
  visit news_path
end

超过 20 个小时来解决这个问题,至少我学到了一些新东西等。

于 2012-06-06T18:41:42.653 回答