问题
Doing Michael Hartl's Rails Tutorial, on chapter 10, section 5, exercise 2. I am - very simply - trying to write tests to ensure that a pagination div appears on a couple pages using the will_paginate gem (this seems to be Hartl's preferred method of testing whether pagination works), but when I add the following code..
subject { page }
.
.
.
it { should have_selector('div.pagination') }
..it returns..
1) UserPages profile page
Failure/Error: it { should have_selector('div.pagination') }
expected css "div.pagination" to return something
This is especially odd because in this particular _spec file, this same Rspec code is passing in some tests and failing in others (I'll highlight this below). Also the pagination
div is present in the source code in my browser, and of course it's working fine.
Because it fails in some places and not others, I got to assuming that this is somehow a "scope"- or assignment-type issue related to will_paginate
- you see, for the failed tests, the content being paginated is actually part of a "Microposts" controller, but the pages/views being tested are handled by the "Users" controller. For the passing tests, the view and controller are both "Users".
Could that be the problem? It's also possible that my FactoryGirl setup/invocation is broken and not triggering the pagination code in test for some reason. I'm a Rails n00b - and actually totally new to programming - so thanks ya'll. :)
(also, p.s., how do I make my code colorful and pretty on SO?)
/spec/requests/user_pages_spec.rb
require 'spec_helper' # Omitted from below - I don't think this is relevant.
describe "UserPages" do
subject { page }
describe "index" do # This is the block where it is PASSING..
let(:user) { FactoryGirl.create(:user) } # I'll include my /spec/factories.rb file below
before(:all) { 30.times { FactoryGirl.create(:user) } }
after(:all) { User.delete_all } # I'll omit my /app/models/user.rb file - I don't think it's relevant to the problem
before do
valid_signin user # References /spec/support/utilities.rb to sign in as a valid user, but I will omit this since this is part of the working tests
visit users_path # This is /app/views/users/index.html.erb - this is where SUCCESSFUL pagination testing occurs
end
describe "pagination" do
it { should have_selector('div.pagination') } #PASS!! As I would expect
.
.
.
end
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
let!(:m1) { FactoryGirl.create(:micropost, user: user, content: "Awesome")} # Used for other tests
let!(:m2) { FactoryGirl.create(:micropost, user: user, content: "Sauce") } # Used for other tests
before(:all) { 30.times { FactoryGirl.create(:micropost) } } # Is this constructed properly? Perhaps the posts are not created, and that's why the failure to render the paginate code in test.
after(:all) { user.microposts.delete_all } # I have tested with and without this line of code - it fails both ways.
before { visit user_path(user) } # /app/views/users/show.html.erb
it { should have_selector('div.pagination') } # FAIL!!! This is the line in question that generates the error above.
.
.
.
.
end
/app/views/users/index.html.erb (pagination working on site, test working also)
<%= provide(:title, 'All users') %>
<h1>All users</h1>
<%= will_paginate %>
<ul class="users">
<%= render @users %>
</ul>
<%= will_paginate %>
/app/views/users/show.html.erb (pagination working on site, test failing)
<% provide(:title, @user.name) %>
<div class="row">
.
.
.
<div class="span8">
<% if @user.microposts.any? %>
<h3>Microposts (<%= @user.microposts.count %>)</h3>
<ol class="microposts">
<%= render @microposts %>
</ol>
<%= will_paginate @microposts %> # Here is where I declare that pagination should occur on @microposts, NOT @users
<% end %>
</div>
</div>
/spec/requests/factories.rb
FactoryGirl.define do
factory :user do
sequence(:name) { |n| "Person #{n}" }
sequence(:email) { |n| "person_#{n}@example.com" }
password "secret"
password_confirmation "secret"
factory :admin do
admin true
end
end
factory :micropost do
content "Lorem ipsum"
user
end
end
/Gemfile
source 'https://rubygems.org'
gem 'rails', '3.2.3'
gem 'pg', '0.12.2'
gem 'bootstrap-sass', '2.0.0'
gem 'bcrypt-ruby', '3.0.1'
gem 'faker', '1.0.1'
gem 'will_paginate', '3.0.3'
gem 'bootstrap-will_paginate', '0.0.6'
group :development do
gem 'guard-rspec', '0.5.5'
gem 'annotate', '~> 2.4.1.beta'
end
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', '3.2.4'
gem 'coffee-rails', '3.2.2'
gem 'uglifier', '1.2.3'
end
gem 'jquery-rails', '2.0.0'
group :test, :development do
gem 'rspec-rails', '2.9.0'
end
group :test do
gem 'capybara', '1.1.2'
gem 'rb-fsevent', '0.4.3.1', :require => false
gem 'growl', '1.0.3'
gem 'guard-spork', '0.3.2'
gem 'spork', '0.9.0'
gem 'factory_girl_rails', '1.4.0'
end
edit: found this article related to will_paginate and view testing, but don't understand it honestly (probably due to the syntax).. could it be somehow related?
回答1:
When you use:
before(:all) { 30.times { FactoryGirl.create(:user) } }
You already have an user created so the total count goes up to 31 and so it paginates (pagination with will_paginate shows 30 records per page by default).
Try creating 31 microposts instead of 30, it should pass.
before(:each) { 31.times { FactoryGirl.create(:micropost, user: user) } }
Edit: I forgot to pass the :user to the micropost Factory, it should work now (is the code I have on my tests and it passes)
回答2:
According to http://thewebfellas.com/blog/2008/8/3/roll-your-own-pagination-links-with-will_paginate
"<%= will_paginate %>
" produces a div tag with class = pagination
, but I didn't see anything that would imply making testing for 'div.pagination'
pass.
I changed the test to
it { should have_selector('div', class: 'pagination') }
and that should basically test the same thing, and this passes for me. Hope this helps!
回答3:
<%= provide (:title, 'All users') %>
<h1>All users</h1>
<div class="pagination">
<%=will_paginate%>
</div>
<ul class="users">
<%=render @users%>
</ul>
<div class="pagination">
<%= will_paginate %>
</div>
来源:https://stackoverflow.com/questions/10762896/testing-views-with-will-paginate-gem-using-capybara-rspec