1
votes

I've been working on Michael Hartl's Rails tutorial app to basically make a replica of twitter. I'm running into a problem in my test suite. One difference between my code and Hartl's code is that I didn't feel like installing FactoryGirl to generate test users, so I create a user at the beginning of the test. I feel like this may be part of the issue but would like to understand what exactly is wrong. My test script below (I'm getting the error at the line: fill_in "Email", with: user.email):

describe "Authentication" do 
subject {page}
before do
    @user = User.create(name: "Example User", email: "[email protected]", 
          password: "foobar", password_confirmation: "foobar")
end

describe "signin page" do
    before { visit signin_path }

    describe "with invalid information" do
        before { click_button "Sign in"}

        it { should have_selector('title', text: 'Sign in')}
        it { should have_selector('div.alert.alert-error', text: 'Invalid')}

    end



    describe "with valid information" do
        let(:user) { User.find_by_email(@user.email) }

        fill_in "Email", with: user.email
        fill_in "Password", with: user.password
        click_button "Sign in"
    end

    it { should have_selector('title', text: user.name) }
    it { should have_link('Profile', href: user_path(user)) }
    it { should have_link('Sign out', href: signout_path) }
    it { should_not have_link('Sign in', href: signin_path) }
    it { should have_link('Sign out')}


    describe "after visiting another page" do
        before { click_link "Home" }
        it { should_not have_selector('div.alert.alert-error') }
    end
end

end

UPDATE: Managed to resolve on my own - I ended up resolving by creating the user instance within the describe with valid information block like so, then referring directly to the instance I created instead of using the let(:user) method.

'describe "with valid information" do before do @user = User.create(name: "Example User", email: "[email protected]", password: "foobar", password_confirmation: "foobar")

        fill_in "Email", with: @user.email
        fill_in "Password", with: @user.password
        click_button "Sign in"
    end


    it { should have_selector('title', text: @user.name) }
    it { should have_link('Profile', href: user_path(@user)) }
    it { should have_link('Sign out', href: signout_path) }
    it { should_not have_link('Sign in', href: signin_path) }
    it { should have_link('Sign out')}
end'
2

2 Answers

1
votes

I think what you should do is just:

describe "Authentication" do 
  subject { page }

  let!(:user) do
    User.create(name: "Example User", email: "[email protected]", 
      password: "foobar", password_confirmation: "foobar")
  end

  describe "signin page" do
    before { visit signin_path }

    describe "with invalid information" do
      before { click_button "Sign in"}

      it { should have_selector('title', text: 'Sign in')}
      it { should have_selector('div.alert.alert-error', text: 'Invalid')}
    end

    describe "with valid information" do
      fill_in "Email", with: user.email
      fill_in "Password", with: user.password
      click_button "Sign in"
    end

    it { should have_selector('title', text: user.name) }
    it { should have_link('Profile', href: user_path(user)) }
    it { should have_link('Sign out', href: signout_path) }
    it { should_not have_link('Sign in', href: signin_path) }
    it { should have_link('Sign out')}

    describe "after visiting another page" do
      before { click_link "Home" }

      it { should_not have_selector('div.alert.alert-error') }
    end
  end
end

What let! does it instantiates the user accessor, puts into before block and reset after every example.

2
votes

You didn't wrap this lines to it block. For example

 it "can sign up" do
   fill_in "Email", with: user.email
   fill_in "Password", with: user.password
   click_button "Sign in"
 end