2012-12-02 16 views
7

Tôi có một phương pháp trong ApplicationHelper của tôi để kiểm tra để xem nếu có bất kỳ mục trong giỏ của tôiTruy cập vào phiên từ một spec helper trong rspec

module ApplicationHelper 
    def has_basket_items? 
    basket = Basket.find(session[:basket_id]) 
    basket ? !basket.basket_items.empty? : false 
    end 
end 

Dưới đây là đặc tả helper của tôi mà tôi phải kiểm tra này:

require 'spec_helper' 

describe ApplicationHelper do 
    describe 'has_basket_items?' do 
    describe 'with no basket' do 

     it "should return false" do 
     helper.has_basket_items?.should be_false 
     end 

    end 
    end 
end 

tuy nhiên khi tôi chạy thử nghiệm tôi nhận được

SystemStackError: stack level too deep 
/home/user/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/testing/test_process.rb:13: 

Từ gỡ lỗi này tôi thấy rằng phiên đang được truy cập trong ActionDispatch :: TestProcess từ @ request.session và @request là không. Khi tôi truy cập phiên từ thông số yêu cầu của tôi @request là một cá thể của ActionController :: TestRequest.

Câu hỏi của tôi là tôi có thể truy cập đối tượng phiên từ thông số trợ giúp không? Nếu tôi có thể, làm thế nào? Và nếu tôi không thể thực hành tốt nhất để kiểm tra phương pháp này là gì?

****CẬP NHẬT* ***

Đây là xuống để có include ActionDispatch::TestProcess tại các nhà máy của tôi. Loại bỏ điều này bao gồm sắp xếp sự cố.

+3

Để đính kèm tệp bằng FactoryGirl và không có "ActionDispatch :: TestProcess", hãy sử dụng: 'image {Rack :: Test :: UploadedFile.new ('spec/factories/test.png', 'image/png')}' , xem: https://gist.github.com/rugginoso/4079399 và https://github.com/gregbell/active_admin/issues/512 –

Trả lời

3

tôi có thể truy cập vào đối tượng session từ một spec helper?

Có.

module ApplicationHelper 
    def has_basket_items? 
    raise session.inspect 
    basket = Basket.find(session[:basket_id]) 
    basket ? !basket.basket_items.empty? : false 
    end 
end 

$ rspec spec/helpers/application_helper.rb 

Failure/Error: helper.has_basket_items?.should be_false 
    RuntimeError: 
    {} 

Đối tượng phiên có ở đó và trả về giá trị băm rỗng.

Hãy thử xem lại backtrace chi tiết hơn để tìm lỗi. stack level too deep thường cho biết đệ quy đã biến mất.

+0

Thật không may là cho cùng một lỗi quá sâu. Gỡ lỗi đệ quy đi đến phương thức phiên trong ActionDispatch :: TestProcess gọi '@ request.session' và @request là nil. '@ request.session' dường như gọi phiên trên ActionDispatch :: TestProcess và vì vậy vòng lặp này cho đến khi ngăn xếp quá sâu. Từ điều này tôi nghĩ rằng tôi cần phải bằng cách nào đó tiêm một phiên vào helper, nhưng tôi không thể dường như làm việc ra như thế nào. –

+0

Tôi đã chạy mã trong câu trả lời của mình và nhận hàm băm rỗng làm đầu ra. Điều đó gợi ý điều gì đó có thể sai với môi trường của bạn. Tôi muốn thử một Rails sạch cài đặt vào một dự án mới, xem nếu vấn đề vẫn còn tồn tại. – zetetic

+0

Ok, vì vậy sau một chút thử nghiệm tôi thấy rằng đó là đá quý 'factory_girl_rails' gây đau đầu, điều này khá khó chịu vì tôi có hàng trăm thử nghiệm sử dụng nó. Tôi sẽ xem nếu có bất kỳ sửa chữa nào cho nó, nếu không có vẻ như tôi sẽ phải tìm một sự thay thế cho cô gái nhà máy. Cám ơn đã chỉ tôi hướng đi đúng. –

1

Bạn đang thử nghiệm has_basket_items? hành động trong ApplicationHelper, mà kiểm tra một giỏ specfic với một basket_id trong bảng giỏ, vì vậy bạn nên có một số đối tượng giỏ trong thử nghiệm của bạn mà bạn có thể tạo bằng cách sử dụng đá quý Factory_Girl.

Hers là một ví dụ: -

basket1 = Factory(:basket, :name => 'basket_1') 
basket2 = Factory(:basket, :name => 'basket_2') 

Bạn có thể biết thêm chi tiết về Làm thế nào để sử dụng factory_girl từ màn hình này đúc http://railscasts.com/episodes/158-factories-not-fixtures

Nó sẽ tạo ra một đối tượng Factory trong cơ sở dữ liệu thử nghiệm của bạn. Vì vậy, về cơ bản bạn có thể tạo một số đối tượng nhà máy và sau đó thiết lập một basket_id trong phiên để kiểm tra sự tồn tại của nó như thế này:

session[:basket_id] = basket1.id 

Vì vậy, kiểm tra của bạn nên được như thế này: -

require 'spec_helper' 

describe ApplicationHelper do 
    describe 'has_basket_items?' do 
    describe 'with no basket' do 

     it "should return false" do 
     basket1 = Factory(:basket, :name => 'basket_1') 
     basket2 = Factory(:basket, :name => 'basket_2') 
     session[:basket_id] = 1234 # a random basket_id 
     helper.has_basket_items?.should be_false 
     end 

    end 
    end 
end 

Ngoài ra, bạn có thể kiểm tra một basket_id đang được tạo ra bởi factory_girl để be_true bằng cách sử dụng:

session[:basket_id] = basket1.id 
helper.has_basket_items?.should be_true 
+0

Tôi đã thử đề xuất của bạn nhưng tiếc là tôi nhận được kết quả tương tự. Từ những gì tôi có thể nói điều này có vẻ là nhiều hơn để thực tế là một đối tượng yêu cầu đã không được tiêm vào helper của tôi hơn là các đối tượng không tồn tại trong cơ sở dữ liệu. Trên thực tế, không có thực thể giỏ nào phải tồn tại để phương pháp của tôi hoạt động. –