Eric Baldwin
Eric Baldwin

Reputation: 3491

"before :each do" block not being run in rspec

In an rspec test, I have tried to initialize two variables before tests are run as follows

  describe "Publishing" do
    before :each do
      page_published = Page.create(attributes_for(:page))
      page_unpublished = Page.create(attributes_for(:page_unpublished))
    end
    it "returns published pages" do
      expect(Page.published).to eq [page_published]
    end
    it "returns unpublished pages" do 
      expect(Page.unpublished).to eq [page_unpublished]
    end
  end

When I do this, I get an error:

1) Page Publishing returns unpublished pages
     Failure/Error: expect(Page.unpublished).to eq [page_unpublished]
     NameError:
       undefined local variable or method `page_unpublished' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_4:0x0000010355b8c0>

However, if I define the variables in each it block, there is no error. Eg:

  describe "Publishing" do
    it "returns published pages" do
      page_published = Page.create(attributes_for(:page))
      expect(Page.published).to eq [page_published]
    end
    it "returns unpublished pages" do 
      page_unpublished = Page.create(attributes_for(:page_unpublished))
      expect(Page.unpublished).to eq [page_unpublished]
    end
  end

Why aren't the variables declared in the "before :each do" block being recognized in it blocks?

Upvotes: 2

Views: 2081

Answers (2)

tsm
tsm

Reputation: 3658

meagar is right. But this is also a prime place to use a let! block instead, making it:

  describe "Publishing" do

    let! :page_published { Page.create(attributes_for(:page)) }
    let! :page_unpublished { Page.create(attributes_for(:page_unpublished)) }

    it "returns published pages" do
      expect(Page.published).to eq [page_published]
    end
    it "returns unpublished pages" do 
      expect(Page.unpublished).to eq [page_unpublished]
    end
  end

Upvotes: 1

user229044
user229044

Reputation: 239240

Because you're declaring them as variables local to the each block, which immediately go out of scope. You need to declare them as instance variables to make them available to other methods:

before :each do
  @page_published = Page.create(attributes_for(:page))
  @page_unpublished = Page.create(attributes_for(:page_unpublished))
end

Upvotes: 4

Related Questions