2012-05-10 27 views
20

Tôi đang cố gắng tạo phương thức trên một trình trợ giúp được xác định trong bộ điều khiển của tôi. Ví dụ:Không thể tạo phương thức trợ giúp với rspec

class ApplicationController < ActionController::Base 
    def current_user 
    @current_user ||= authenticated_user_method 
    end 
    helper_method :current_user 
end 

module SomeHelper 
    def do_something 
    current_user.call_a_method 
    end 
end 

Trong RSpec tôi:

describe SomeHelper 
    it "why cant i stub a helper method?!" do 
    helper.stub!(:current_user).and_return(@user) 
    helper.respond_to?(:current_user).should be_true # Fails 
    helper.do_something # Fails 'no method current_user' 
    end 
end 

Trong spec/support/authentication.rb

module RspecAuthentication 
    def sign_in(user) 
    controller.stub!(:current_user).and_return(user) 
    controller.stub!(:authenticate!).and_return(true) 

    helper.stub(:current_user).and_return(user) if respond_to?(:helper) 
    end 
end 

RSpec.configure do |config| 
    config.include RspecAuthentication, :type => :controller 
    config.include RspecAuthentication, :type => :view 
    config.include RspecAuthentication, :type => :helper 
end 

Tôi hỏi một câu hỏi tương tự here, nhưng giải quyết trên một công trình xung quanh. Hành vi kỳ lạ này đã leo lên một lần nữa và tôi muốn hiểu lý do tại sao công việc này không hoạt động.

CẬP NHẬT: Tôi nhận thấy rằng gọi controller.stub!(:current_user).and_return(@user) trước helper.stub!(...) là nguyên nhân gây ra hành vi này. Điều này là dễ dàng, đủ để sửa chữa trong spec/support/authentication.rb, nhưng đây có phải là một lỗi trong Rspec? Tôi không thấy lý do tại sao nó sẽ được dự kiến ​​sẽ không có thể stub một phương pháp trên một helper nếu nó đã được stubbed trên một bộ điều khiển.

+0

Hãy thử stubbing phương pháp thông qua ApplicationController, vì đó là nơi nó được định nghĩa. 'ApplicationController.stub (: current_user => @user)' EDIT: Bây giờ tôi nghĩ rằng có thể không hoạt động. – dwhalen

+0

Không, nó không hoạt động. Tôi đã thử 'any_instance' cũng không có may mắn. Tôi đã thực sự có nó làm việc, nhưng tôi là một chút bối rối (có thể đã tìm thấy một lỗi với rspec). Tôi sẽ sớm cập nhật câu hỏi. – Brad

+0

Âm thanh như một lỗi. Nó chắc chắn là giá trị nộp một vấn đề tại https://github.com/rspec/rspec-mocks/issues (và cố gắng với phiên bản mới nhất). –

Trả lời

8

Hãy thử điều này, nó làm việc cho tôi:

describe SomeHelper 
    before :each do 
    @helper = Object.new.extend SomeHelper 
    end 

    it "why cant i stub a helper method?!" do 
    @helper.stub!(:current_user).and_return(@user) 
    # ... 
    end 
end 

Phần thứ nhất được dựa trên this reply bởi tác giả của RSpec, và phần thứ hai là dựa trên this Stack Overflow answer.

+0

... và sau đó các thử nghiệm thực sự cần phải kiểm tra @helper, không phải SomeHelper. – LisaD

+0

nó không hoạt động – Jerry

20

Cập nhật câu trả lời của Matthew Ratzloff: Bạn không cần đối tượng thể hiện và sơ khai! đã không được chấp nhận

it "why can't I stub a helper method?!" do 
    helper.stub(:current_user) { user } 
    expect(helper.do_something).to eq 'something' 
end 

Chỉnh sửa. Các RSpec 3 cách để stub! sẽ là:

allow(helper).to receive(:current_user) { user }

Xem: https://relishapp.com/rspec/rspec-mocks/v/3-2/docs/

+2

nó không hoạt động. – Chamnap

+0

Tôi đã sửa câu trả lời cho RSpec 3. –

2

RSpec 3

user = double(image: urlurl) 
    allow(helper).to receive(:current_user).and_return(user) 
    expect(helper.get_user_header).to eq("/uploads/user/1/logo.png") 
1

Trong RSpec 3,5 RSpec, nó có vẻ như helper không còn được truy cập từ một it khối. (Nó sẽ cung cấp cho bạn thông báo sau:

helper không có sẵn từ bên trong một ví dụ (ví dụ như một khối it) hoặc từ các cấu trúc mà chạy trong phạm vi của một ví dụ (ví dụ before, let, vv) It. chỉ có sẵn trên một nhóm ví dụ (ví dụ như một describe hoặc context khối).

(tôi dường như không thể tìm thấy bất kỳ tài liệu về sự thay đổi này, đây là tất cả các kiến ​​thức thu được bằng thực nghiệm).

Chìa khóa để giải quyết này được biết rằng phương pháp helper là phương pháp dụ, và điều đó cho các phương pháp helper của riêng bạn thật dễ dàng để làm điều này:

allow_any_instance_of(SomeHelper).to receive(:current_user).and_return(user) 

Đây là những gì cuối cùng làm việc cho tôi

Chú thích/tín dụng ở đâu Credit Do:

0

này làm việc cho tôi trong trường hợp RSpec 3:

let(:user) { create :user } 
helper do 
    def current_user; end 
end 
before do 
    allow(helper).to receive(:current_user).and_return user 
end 
Các vấn đề liên quan