I have a test that needs to loop through 5 elements in an array then verify that all the elements are displayed as list items on the page. I have the code below, it's the last test with the comment '#get the first 5 blog posts'. When I run the tests, this test is not seen, because only 4 tests are getting executed. If I move the 'it {} ' statement outside the array code blog, the test becomes visible. How do I properly write this test so it can loop correctly?
require 'spec_helper'
require 'requests/shared'
describe "Header" do
let (:title) { "my title" }
subject { page }
before { visit root_path }
describe "Home" do
it { should have_selector('title', text: title) }
it { should have_selector('header') }
it { should have_link 'Home', href: root_path}
describe "Blog link exist" do
it { should have_link 'Blog'}
end
describe "Blog list elements" do
#get the first 5 blog posts
Blog.all(limit:5).each do |blog|
it { should have_selector('ul.accordmobile li#blog ul li a', text: blog.title, href: blog_path(blog.id)) }
end
end
end
end
You can't have your test nested that way due to RSpec being a DSL. RSpec reads the example spec files first, before running the tests. So it hits the Blog.all
before any of the tests are run. This also means that there is no population of the database. So unless there was leftover state from a previous test run Blog.all
will return []
.
Trying to create the objects in a before
will not work either with the way the test is written in your question. Again, this is due to Blog.all
being executed at parse time, while before
is executed at test time.
In order to achieve what you want, you will probably need to break the "only test one thing" rule and nest the Blog.all
inside the it
block:
it "list the first five posts" do
Blog.all(limit:5).each do |blog|
expect(page).to have_selector('ul.accordmobile li#blog ul li a',
text: blog.title,
href: blog_path(blog.id))
end
end
important! for hoping loop, to run you should have 5 or more than 5 blogs.
than do
may be this should be re-factored as
Blog.limit(5).each do |blog|
it { should have_selector('ul.accordmobile li#blog ul li a', text: blog.title, href: blog_path(blog.id)) }
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With