2011-09-16 22 views
55

Tôi cần phải đưa ra phản hồi của phương thức current_user trong thông số yêu cầu Rspec/capybara. Phương thức được định nghĩa trong ApplicationController và đang sử dụng helper_method. Phương thức này chỉ cần trả về một id người dùng. Trong thử nghiệm, tôi muốn phương thức này trả về cùng một id người dùng mỗi lần.Làm thế nào để khai phương pháp ApplicationController theo yêu cầu spec

Ngoài ra, tôi có thể khắc phục sự cố của mình bằng cách đặt session[:user_id] trong thông số kỹ thuật (đó là những gì current_user trả về) ... nhưng điều đó dường như không hoạt động.

Có thể thực hiện một trong hai tùy chọn này không?

Chỉnh sửa:

Đây là những gì tôi có (nó không hoạt động. Nó chỉ chạy phương pháp current_user bình thường).

require 'spec_helper' 

describe "Login" do 

    before(:each) do 
    ApplicationController.stub(:current_user).and_return(User.first) 
    end 

    it "logs in" do 
    visit '/' 
    page.should have_content("Hey there user!") 
    end 

end 

Cũng không làm việc:

require 'spec_helper' 

describe "Login" do 

    before(:each) do 
    @mock_controller = mock("ApplicationController") 
    @mock_controller.stub(:current_user).and_return(User.first) 
    end 

    it "logs in" do 
    visit '/' 
    page.should have_content("Hey there user!") 
    end 

end 
+13

là 'current_user' một phương pháp lớp học? Tôi đoán không. Vì vậy, thay vì 'ApplicationController.stub (: current_user)' bạn có thể cần 'ApplicationController.any_instance.stub (: current_user)'. – skalee

Trả lời

13

Dưới đây là một vài ví dụ về các hình thức cơ bản.

controller.stub(:action_name).and_raise([some error]) 
controller.stub(:action_name).and_return([some value]) 

Trong trường hợp cụ thể của bạn, tôi tin rằng các hình thức thích hợp sẽ là:

controller.stub(:current_user).and_return([your user object/id]) 

Dưới đây là một ví dụ làm việc đầy đủ từ một dự án tôi làm việc trên:

describe PortalsController do 

    it "if an ActionController::InvalidAuthenticityToken is raised the user should be redirected to login" do 
    controller.stub(:index).and_raise(ActionController::InvalidAuthenticityToken) 
    get :index 
    flash[:notice].should eql("Your session has expired.") 
    response.should redirect_to(portals_path) 
    end 

end 

Để giải thích đầy đủ của tôi Ví dụ, về cơ bản những gì điều này làm là xác minh rằng, khi một lỗi ActionController::InvalidAuthenticityToken được nâng lên bất cứ nơi nào trong ứng dụng, thông báo flash xuất hiện và người dùng được chuyển hướng đến portals_controller#index actio n. Bạn có thể sử dụng các biểu mẫu này để phát hành và trả về các giá trị cụ thể, kiểm tra một trường hợp của một lỗi cụ thể được nêu ra, v.v. Có một số phương thức .stub(:action_name).and_[do_something_interesting]() có sẵn cho bạn.


Cập nhật (sau khi bạn đã thêm mã của bạn): Theo nhận xét của tôi, thay đổi mã của bạn để nó đọc:

require 'spec_helper' 

describe "Login" do 

    before(:each) do 
     @mock_controller = mock("ApplicationController") 
     @mock_controller.stub(:current_user).and_return(User.first) 
    end 

    it "logs in" do 
    visit '/' 
    page.should have_content("Hey there user!") 
    end 

end 
+0

Cảm ơn phản hồi của bạn, nhưng trông giống như thông số bộ điều khiển, trái ngược với thông số yêu cầu. Tôi khá mới để thử nghiệm, vì vậy tôi có thể sai :) –

+0

Stub chỉ hoạt động như một replacer cho bất kỳ phương pháp được định nghĩa trên bất kỳ lớp học. Trong ví dụ bạn đưa ra, nó là một phương thức 'current_user' được định nghĩa trên' ApplicationController', đúng không? Hình thức cơ bản tương tự sẽ hoạt động, trừ khi tôi hiểu nhầm câu hỏi của bạn. Bạn có thể đăng hình thức tốt nhất của bài kiểm tra bạn đã viết, ngay cả khi nó không hoạt động? – jefflunt

+0

Vì vậy, tôi đã giả định rằng thử nghiệm của bạn là bên trong một spec bắt đầu với 'mô tả ApplicationController', do đó, xấu của tôi ở đó. Nếu đó không phải là trường hợp, thì bạn vẫn có thể thực hiện 'ApplicationController.stub (: current_user) .and_return ([đối tượng người dùng/id])' – jefflunt

57

skalee dường như đã cung cấp câu trả lời đúng trong các nhận xét.

Nếu phương pháp bạn đang cố gắng sơ khai là một phương pháp dụ (rất có thể) và không phải là một phương pháp lớp học thì bạn cần sử dụng:

ApplicationController.any_instance.stub(:current_user)

+25

Điều này vẫn hoạt động đối với Rspec 3 nhưng cho cảnh báo không dùng nữa. Đây là cú pháp mới: 'allow_any_instance_of (ApplicationController) .to nhận (: current_user).and_return (your_test_user) ' – Sharagoz

+1

Yêu dấu trích dẫn này -" Sử dụng tính năng này thường là mùi thiết kế "- từ [tài liệu Rspec] (https://github.com/rspec/rspec-mocks). – brntsllvn

3

này làm việc cho tôi và mang lại cho tôi một biến @current_user để sử dụng trong các bài kiểm tra.

Tôi có một helper trông như thế này:

def bypass_authentication 
    current_user = FactoryGirl.create(:user) 

    ApplicationController.send(:alias_method, :old_current_user, :current_user) 
    ApplicationController.send(:define_method, :current_user) do 
    current_user 
    end 
    @current_user = current_user 
end 

def restore_authentication 
    ApplicationController.send(:alias_method, :current_user, :old_current_user) 
end 

Và sau đó trong thông số kỹ thuật yêu cầu của tôi, tôi gọi:

before(:each){bypass_authentication} 
after(:each){restore_authentication} 
2

Đối với bất kỳ ai khác xảy ra cần phải còn sơ khai một phương pháp điều khiển ứng dụng mà đặt một ivar (và được stymied bởi wanking bất tận về lý do tại sao bạn không nên làm điều đó) đây là một cách mà làm việc, với hương vị của Rspec vào khoảng tháng 10 năm 2013.

before(:each) do 
    campaign = Campaign.create! 
    ApplicationController.any_instance.stub(:load_campaign_singleton) 
    controller.instance_eval{@campaign = campaign} 
    @campaign = campaign 
end 

nó khai báo phương thức để không làm gì và đặt ivar trên cá thể bộ điều khiển của rspec và làm cho nó có sẵn cho thử nghiệm dưới dạng @campaign.

+0

Công cụ trễ để kết thúc cuộc đọ sức bất tận nhưng chỉ trong thời gian để giữ tôi không ném máy tính của tôi ra ngoài cửa sổ. Cảm ơn! – eggmatters

1

Không có câu trả lời nào được cung cấp cho tôi. Như trong bài đăng gốc của @ matt-fordam, tôi có thông số yêu cầu, không phải là thông số của bộ điều khiển. Bài kiểm tra chỉ hiển thị chế độ xem mà không cần khởi chạy bộ điều khiển.

tôi giải quyết điều này bằng cách stubbing phương pháp trên quan điểm như mô tả trong này other SO post

view.stub(:current_user).and_return(etc) 
Các vấn đề liên quan