Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need to loop through an array in rspec, test not running

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

like image 430
Wale Avatar asked May 22 '13 17:05

Wale


2 Answers

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
like image 73
Aaron K Avatar answered Nov 11 '22 17:11

Aaron K


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
like image 42
Sachin Singh Avatar answered Nov 11 '22 18:11

Sachin Singh