简体   繁体   中英

Rspec/Rails 4: Failure/Error: visit “/todos” NoMethodError: undefined method `todos' for nil:NilClass in rspec test

Failed to make my test pass. Can someone pointme what am missing. I am testing the index page of the todos(which is single page application).

Error Log:

1) Displaying todos should display the list of todos
 Failure/Error: visit "/todos"
 NoMethodError:
   undefined method `todos' for nil:NilClass
 # ./app/controllers/todos_controller.rb:6:in `index'
 # ./spec/features/todos/index_spec.rb:24:in `block (2 levels) in <top (required)>'

todos_controller.rb

 class TodosController < ApplicationController

skip_before_action :authenticate_user!

 def index
 @todos_completed_today = current_user.todos.where(is_completed: true).
 where("updated_at  >= ?", (Time.zone.now - 24.hours)).order('todos.position ASC')

 @todos = current_user.todos.where(is_completed: false).order('todos.position ASC'
 end

 def create
  @todo = current_user.todos.new(todo_params)
  @todo.save
   respond_to do |format|
    format.html { redirect_to todos_path }
    format.js
  end
 end

 def edit
  @todo = current_user.todos.find_by_id(params[:id])
 end

 def update
  @todo = current_user.todos.find_by_id(params[:id])
  @todo.update_attributes(todo_params)
 end

Here is my todo index spec. features/todos/index_spec.rb

 describe "Displaying todos", :js => true do
   let(:todo) { FactoryGirl.create(:todo)}

    it "should display the list of todos" do

      visit "/todos"

     expect(Todo.count).to eq(0)
    page.should have_selector('h1', :text => 'Todos')


    fill_in "title", with: "MyString"
    click_button "Create"

   expect(page).to have_content("Todo has been created!")
   expect(todo.todo_title).to eq(title)

  todo.reload!
  expect(Todo.count).to eq(1)
  expect(todo.title).eq("Mystring")
 end

factories/todo.rb

# Read about factories at https://github.com/thoughtbot/factory_girl

  FactoryGirl.define do
    factory :todo do
    title "MyString"
    description "MyText"
    is_completed false
    position 1
   end
 end

spec/support/devise.rb

module FeatureMacros
  def login_user_in_feature
    Warden.test_reset!
    Warden.test_mode!
    user = create(:user)
    login_as user, :scope => :user
    user.confirmed_at = Time.now
    user.confirm!
    user.save
    user
  end
end

RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller
  config.include Devise::TestHelpers, :type => :view
  config.include Warden::Test::Helpers
  config.include FeatureMacros
end

In factories/user.rb

FactoryGirl.define do
  factory :user do
    #your user factory
  end
end

In factories/todo.rb

FactoryGirl.define do
  factory :todo do
    title "MyString"
    description "MyText"
    is_completed false
    position 1
    user{User.last}
  end
end

In features/todos/index_spec.rb

feature "Displaying todos", :js => true do
  scenario "should display the list of todos" do
    login_user_in_feature
    todo = FactoryGirl.create(:todo)
    visit "/todos"
    expect(Todo.count).to eq(0)
    page.should have_selector('h1', :text => 'Todos')
    fill_in "title", with: "MyString"
    click_button "Create"
    expect(page).to have_content("Todo has been created!")
    expect(todo.todo_title).to eq(title)
    todo.reload!
    expect(Todo.count).to eq(1)
    expect(todo.title).eq("Mystring")
  end
end

If it did not work or have anything, please tell me, you can see the authentication for the user using FeatureMacros because current_user won't work without it

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM