Rails、Restful Authentication 和 RSpec - 如何测试需要身份验证的新模型
-
09-06-2019 - |
题
我使用创建了一个学习应用程序 博尔特, ,这是一个包含 Restful Authentication 和 RSpec 的基础应用程序。我已经启动并运行了它,并添加了一个新对象,要求用户先登录才能执行任何操作(before_filter :login_required
在控制器中)。[编辑:我还应该提到的是,用户 has_many
新类的内容,只有用户应该能够看到它。]
我使用 Rspec 的生成器创建了新的模型/控制器,该生成器创建了许多默认测试。如果没有的话他们都会通过 before_filter
但正如预期的那样,一旦 before_filter
已就位。
如何让生成的测试像有/没有登录用户一样运行?我是否需要一整批未登录的匹配 - 重定向测试?我认为这是某种模拟或固定技术,但我对 RSpec 很陌生并且有点迷失。好的 RSpec 教程链接也将受到赞赏。
解决方案
我有一个非常相似的设置,下面是我当前用来测试这个东西的代码。在每个 describe
我输入:
it_should_behave_like "login-required object"
def attempt_access; do_post; end
如果您只需要登录,或者
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
如果你需要所有权。显然,辅助方法每次都会发生变化(很少),但这会为您完成大部分工作。这是在我的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
其他提示
当不测试身份验证但测试需要用户身份验证的控制器时,我通常会存根过滤器方法:
before(:each) do
controller.stub!(:authenticate).and_return(true)
end
上面的示例在我的 before_filter 设置为authenticate 方法的情况下有效:
before_filter :authenticate
我的应用程序中的身份验证使用 HTTP 基本身份验证,但它实际上可以是任何其他身份验证机制。
private
def authenticate
authenticate_or_request_with_http_basic do |user,password|
user == USER_NAME && password == PASSWORD
end
end
我认为这是一种非常简单的测试方法。
我找到了我自己问题的一些答案。基本上,我需要了解如何模拟用户 restful_authentication
这样即使我添加了自动生成的 rspec 控制器测试也可以通过 before_filter: login_required
.
以下是我刚刚找到的一些资源:
rspec、restful_authentication 和 login_required
为了模拟正在登录的用户,我侵入控制器来设置 @current_user
手动:
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