การทดสอบ Ruby ทั้งหมดเพิ่ม: วิธีการที่ไม่ได้กำหนดʻauthenticate 'สำหรับ nil: NilClass


132

การทดสอบส่วนใหญ่ของฉันมีดังต่อไปนี้และฉันไม่เข้าใจว่าทำไม การเรียกวิธีการทั้งหมดทำให้เกิดข้อผิดพลาด 'รับรองความถูกต้อง' ฉันได้ตรวจสอบโค้ดแล้วหากมีวิธีที่เรียกว่า "พิสูจน์ตัวตน" แต่ไม่มีวิธีการดังกล่าว

  1) Admin::CommentsController handling GET to index is successful
     Failure/Error: get :index
     undefined method `authenticate!' for nil:NilClass
     # ./spec/controllers/admin/comments_controller_spec.rb:9:in `block (3 levels) in <top (required)>'


  124) PostsController handling GET for a single post should render show template
     Failure/Error: get :show, :year => '2008', :month => '01', :day => '01', :slug => 'a-post'
     undefined method `authenticate' for nil:NilClass
     # ./app/controllers/application_controller.rb:18:in `set_current_user_for_model'
     # ./spec/controllers/posts_controller_spec.rb:131:in `do_get'
     # ./spec/controllers/posts_controller_spec.rb:140:in `block (3 levels) in <top (required)>'

สามารถพบโครงการได้ที่นั่น => https://github.com/agilepandas/enkiในกรณีที่คุณต้องการทดสอบด้วยตนเอง

คำตอบ:


191

คำถามนี้ได้รับคำตอบบน Twitter โดย @MatthewClosson

@jeffehh คุณต้องสร้างไฟล์ spec / support / devise.rb ตามที่ระบุไว้ที่นี่https://github.com/plataformatec/devise#test-helpersเพื่อรวมตัวช่วยทดสอบประดิษฐ์ #ruby

ขอบคุณอีกครั้ง


2
การบันทึก URL จริง (แทนที่จะเป็น bit.ly): ในหน้าอุปกรณ์ ( github.com/plataformatec/devise ) โปรดดูส่วน "ผู้ช่วยทดสอบ"
Zabba

74

ฉันทราบว่าคุณกำลังใช้ Rspec แต่คุณสามารถพบปัญหาเดียวกันกับTest::Unit. คุณเพียงแค่ต้องเพิ่มตัวช่วยทดสอบอุปกรณ์test/test_helper.rb

class ActiveSupport::TestCase
  include Devise::TestHelpers
end

8

คำตอบข้างต้นไม่ได้ผลสำหรับฉัน (RSpec 3.1)

ดูhttps://stackoverflow.com/a/21166482/1161743สำหรับวิธีแก้ปัญหาที่เหมาะกับฉัน

คุณจะต้องออกจากระบบผู้ใช้ที่ไม่ระบุชื่อก่อนตั้งค่าตัวแปร:

before :each do
  sign_out :user
end

1
ตรวจสอบด้วยว่าคุณไม่ได้รวม Devise :: TestHelpers หลายครั้งเพราะอาจทำให้เกิดปัญหาได้
Joseph Siefers

8

ใน RSpec

ดังที่ Jeffrey W. กล่าวไว้ในคำตอบของเขาด้านบน -> เพื่อตั้งค่านี้ให้กับคอนโทรลเลอร์ทั้งหมด:

RSpec.configure do |config|
  # ...
  config.include Devise::TestHelpers, type: :controller
  # ...
end

อย่างไรก็ตามหากสิ่งนี้เกี่ยวข้องกับข้อมูลจำเพาะเพียงรายการเดียวคุณไม่จำเป็นต้องรวมผู้ช่วยประดิษฐ์ไว้ในข้อกำหนดของคอนโทรลเลอร์ทั้งหมดของคุณคุณสามารถรวมตัวช่วยเหล่านั้นไว้อย่างชัดเจนในตัวควบคุมหนึ่งตัวที่อธิบายถึงบล็อก:

require 'spec_helper'
describe MyCoolController
  include Devise::TestHelpers

  it { } 
end

2

ฉันประสบกับความล้มเหลวเดียวกันในโครงการหนึ่งของฉัน ใช้ Ruby 2.0.0-p598, Rails 3.2.21, RSpec 2.99 เมื่อฉันรันข้อมูลจำเพาะทั้งหมดพร้อมกันปัญหาก็เกิดขึ้น เมื่อฉันวิ่งสเปคทีละรายการพวกเขาก็ผ่าน ฉันมีสิ่งต่อไปนี้รวมอยู่ใน spec / spec_helper.rb ของฉัน:

RSpec.configure do |config|
  # ...
  config.include Devise::TestHelpers, type: :controller
  # ...
end

ฉันเพิ่มสิ่งต่อไปนี้ในคำอธิบายแรกในไฟล์ข้อมูลจำเพาะที่ล้มเหลวแต่ละไฟล์ สิ่งนี้ไม่สามารถแก้ไขปัญหาได้:

before :each do
  sign_out :user
end

ไม่ได้ทำ:

after :each do
  sign_out :user
end

ด้วยแรงบันดาลใจจากคำตอบสำหรับคำถาม stackoverflow นี้ฉันเรียกใช้ชุดรวมของไดเรกทอรี rspec เข้าด้วยกันเพื่อค้นหาว่ารายการใดที่อาจรบกวนซึ่งกันและกัน ในที่สุดฉันก็พบว่าฉันโทรหา:

before() do #note no :each passed to before
  :
end

เมื่อฉันเปลี่ยนเหตุการณ์ทั้งหมดนี้เป็น:

before(:each) do
  :
end

ข้อมูลจำเพาะทั้งหมดผ่านไปโดยไม่เกิดความล้มเหลว:

undefined method `authenticate' for nil:NilClass

ฉันหวังว่านี่จะเป็นการช่วยเหลือผู้อื่น


0

หากคุณกำลังทำงานกับข้อมูลจำเพาะมุมมองคุณสามารถดึงcurrent_userไฟล์. สิ่งนี้จะแทนที่ตัวcurrent_userช่วยที่ถูกเรียกจากมุมมองของคุณอย่างมีประสิทธิภาพด้วยสิ่งที่ส่งกลับมา นี่คือวิธีการกับ rspec-3.2.3:

RSpec.describe "projects/show", type: :view do
  before(:each) do
    allow(view).to receive(:current_user).and_return(FactoryGirl.create(:user))
  end

  it "renders attributes in <p>" do
    render
    expect(rendered).to match(/whatever you want to regex match here/)
  end
end

-3

ดูเหมือนว่ามีการอัปเดตซอร์สโค้ดบางอย่าง ApplicationController ระบุว่าต้องมีการauthenticate_user!รันตัวกรองก่อนคำขอใด ๆ ชุดข้อความนี้ให้ข้อมูลพื้นฐานเกี่ยวกับปัญหา:

http://groups.google.com/group/plataformatec-devise/browse_thread/thread/f7260ebe2d9f7316?fwc=1

โดยพื้นฐานแล้วauthenticate_user!ฟังก์ชันนี้เป็นส่วนหนึ่งของ Rails 3 (โดยใช้deviseคุณสมบัติใหม่ซึ่งฉันไม่ค่อยรู้) หากแอปไม่พบรูปแบบผู้ใช้ (ไม่ว่าจะเป็นเพราะปัญหาเนมสเปซหรือสาเหตุใดก็ตาม) วิธีนี้จะล้มเหลว แอปพลิเคชัน "enki" ที่คุณเชื่อมโยงเป็นแอปพลิเคชัน Rails 3 อาจกำลังประสบกับความเจ็บปวดที่เพิ่มขึ้นเล็กน้อยเมื่อมันเปลี่ยนไป


2
คำตอบนี้เป็นเรื่องไร้สาระที่บริสุทธิ์ 99%
สูงสุด

-20

ทับทิมจะบอกคุณวิธีการที่#authenticateไม่ได้รับการ definded บนnilเลย คุณสามารถทำได้ง่ายๆโดย:

def nil.authenticate!
  puts "Bingo! Nil is now authentic!"
end

และข้อผิดพลาดจะหายไป


1
โปรดอย่าทำเช่นนี้ ศูนย์เป็นศูนย์ไม่ใช่วัตถุที่ถูกต้องใน 90% ของกรณี
Tiago Peczenyj
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.