Вопрос

So I'm running through the Michael Hartl Rails tutorial and just after creating the edit page (end of Listing 9.3), I get the following errors when I run my tests. As far as I know, I defined the sign_in method and make it available in my application controller. Not exactly sure where I went wrong as his tutorial says my tests should pass by this point. Any help is appreciated. (Also, please let me know if I need to include anything else)

Failures:

1) User pages edit page Failure/Error: sign_in user NoMethodError: undefined method sign_in' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_4::Nested_1:0x00000108a92118> # ./spec/requests/user_pages_spec.rb:60:inblock (3 levels) in '

2) User pages edit page Failure/Error: sign_in user NoMethodError: undefined method sign_in' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_4::Nested_1:0x00000108820560> # ./spec/requests/user_pages_spec.rb:60:inblock (3 levels) in '

3) User pages edit page Failure/Error: sign_in user NoMethodError: undefined method sign_in' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_4::Nested_1:0x00000108846be8> # ./spec/requests/user_pages_spec.rb:60:inblock (3 levels) in '

4) User pages edit with invalid information Failure/Error: sign_in user NoMethodError: undefined method sign_in' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_4::Nested_2:0x00000103e6cd60> # ./spec/requests/user_pages_spec.rb:60:inblock (3 levels) in '

Finished in 0.98841 seconds 23 examples, 4 failures

Test Document: user_pages_spec.rb

require 'spec_helper'

    describe "User pages" do

    subject { page }
    .
    .
    .

    describe "edit" do
        let(:user) { FactoryGirl.create(:user) }
        before do
            sign_in user
            visit edit_user_path(user)
        end

        describe "page" do
            it { should have_content("Update your profile") }
            it { should have_title("Edit user") }
            it { should have_link('change', href: 'http://gravatar.com/emails') }
        end

        describe "with invalid information" do
            before { click_button "Save changes" }

            it { should have_content('error') }
        end
    end
end

Session Helper: sessions_helper.rb

module SessionsHelper

    def sign_in(user)
        remember_token = User.new_remember_token
        cookies.permanent[:remember_token] = remember_token
        user.update_attribute(:remember_token, User.encrypt(remember_token))
        self.current_user = user
    end

    def signed_in?
        !current_user.nil?
    end

    def current_user=(user)
        @current_user = user
    end

    def current_user
        remember_token = User.encrypt(cookies[:remember_token])
        @current_user ||= User.find_by(remember_token: remember_token)
    end

    def sign_out
        current_user.update_attribute(:remember_token,
                                      User.encrypt(User.new_remember_token))
        cookies.delete(:remember_token)
        self.current_user = nil
    end
end

Application Controller: application_controller.rb

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  include SessionsHelper
end
Это было полезно?

Решение

This is telling you that sign_in isn't a method in the scope of the test so you can't use it in the before block like that. It's a controller method not a test method.

Simplest approach is to create a spec helper method which does the signing in, which you can call in the context of a before block which sets up state for any test requiring a signed in user.

One way to do this would be I have a "user_signs_in" helper which uses capybara to visit signin path, fill in signin in form with correct details, and then follow redirects.

Related stackoverflow q:

How do I simulate a login with RSpec?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top