2008-09-15 13 views
17

Tôi đã tạo một ứng dụng học tập bằng cách sử dụng Bort, là ứng dụng cơ bản bao gồm Xác thực và RSpec. Tôi đã có nó và chạy và thêm một đối tượng mới mà yêu cầu người dùng phải đăng nhập trước khi họ có thể làm bất cứ điều gì (before_filter :login_required trong bộ điều khiển). [chỉnh sửa: Tôi cũng nên đề cập đến người dùng has_many của lớp mới và chỉ người dùng mới có thể xem được.]Rails, Restful Authentication & RSpec - Cách kiểm tra các mô hình mới yêu cầu xác thực

Tôi đã tạo mô hình/bộ điều khiển mới bằng cách sử dụng trình tạo Rspec đã tạo một số mặc định kiểm tra. Tất cả đều vượt qua nếu không có before_filter nhưng một số lỗi không thành công, như được mong đợi, khi đã có before_filter.

Làm cách nào để các thử nghiệm được tạo chạy như thể có/không phải là người dùng đã đăng nhập? Tôi có cần toàn bộ lô đối sánh chưa đăng nhập - kiểm tra chuyển hướng không? Tôi cho rằng đó là một số loại kỹ thuật chế nhạo hay cố định nhưng tôi mới mẻ với RSpec và một chút nhàn rỗi. Các liên kết hướng dẫn RSpec tốt cũng sẽ được đánh giá cao.

Trả lời

7

Tôi có thiết lập rất giống nhau và bên dưới là mã tôi hiện đang sử dụng để kiểm tra nội dung này. Trong mỗi describe s tôi đặt tại:

it_should_behave_like "login-required object" 
def attempt_access; do_post; end 

Nếu tất cả bạn cần là một đăng nhập, hoặc

it_should_behave_like "ownership-required object" 
def login_as_object_owner; login_as @product.user; end 
def attempt_access; do_put; end 
def successful_ownership_access 
    response.should redirect_to(product_url(@product)) 
end 

Nếu bạn cần sở hữu. Rõ ràng, các phương pháp trợ giúp thay đổi (rất ít) với mỗi lượt, nhưng điều này thực hiện hầu hết công việc cho bạn. Đây là trong số của tôi spec_helper.rb

shared_examples_for "login-required object" do 
    it "should not be able to access this without logging in" do 
    attempt_access 

    response.should_not be_success 
    respond_to do |format| 
     format.html { redirect_to(login_url) } 
     format.xml { response.status_code.should == 401 } 
    end 
    end 
end 

shared_examples_for "ownership-required object" do 
    it_should_behave_like "login-required object" 

    it "should not be able to access this without owning it" do 
    attempt_access 

    response.should_not be_success 
    respond_to do |format| 
     format.html { response.should be_redirect } 
     format.xml { response.status_code.should == 401 } 
    end 
    end 

    it "should be able to access this if you own it" do 
    login_as_object_owner 
    attempt_access 

    if respond_to?(:successful_ownership_access) 
     successful_ownership_access 
    else 
     response.should be_success 
    end 
    end 
end 
4

Tôi đã tìm thấy một vài câu trả lời cho câu hỏi của riêng mình. Về cơ bản, tôi cần phải hiểu làm thế nào để thử người dùng từ restful_authentication để các kiểm tra bộ điều khiển rspec tự động phát hiện có thể vượt qua mặc dù tôi đã thêm before_filter: login_required.

Dưới đây là một vài trong số các nguồn lực vừa phát hiện của tôi:

RSpec: It Should Behave Like

rspec, restful_authentication, and login_required

using restful_authentication current_user inside controller specs

DRYing up your CRUD controller RSpecs

1

Để chế nhạo người dùng được đăng nhập, tôi hack vào điều khiển để đặt @current_user theo cách thủ công:

module AuthHelper 
    protected 

    def login_as(model, id_or_attributes = {}) 
    attributes = id_or_attributes.is_a?(Fixnum) ? {:id => id} : id_or_attributes 
    @current_user = stub_model(model, attributes) 
    target = controller rescue template 
    target.instance_variable_set '@current_user', @current_user 

    if block_given? 
     yield 
     target.instance_variable_set '@current_user', nil 
    end 
    return @current_user 
    end 

    def login_as_user(id_or_attributes = {}, &block) 
    login_as(User, id_or_attributes, &block) 
    end 
end 
7

Khi không kiểm tra xác thực nhưng thử nghiệm các bộ điều khiển mà cần người dùng phải được xác thực Tôi thường còn sơ khai phương pháp lọc:

before(:each) do 
    controller.stub!(:authenticate).and_return(true) 
end 

Ví dụ trên làm việc nơi before_filter của tôi được thiết lập để các phương pháp xác thực :

before_filter :authenticate 

và xác thực trong ứng dụng của tôi sử dụng Xác thực cơ bản HTTP, nhưng nó thực sự có thể là cơ chế xác thực khác.

private 
def authenticate 
    authenticate_or_request_with_http_basic do |user,password| 
    user == USER_NAME && password == PASSWORD 
    end 
end 

Tôi nghĩ đây là một cách khá đơn giản để kiểm tra.

+0

Người ngọt ngào nhất! – AnkitG