Ruby on rails 通过函数生成RSpec示例
我正在尝试添加一个函数,以便为未经身份验证的用户快速测试重定向。以下是我目前掌握的情况:Ruby on rails 通过函数生成RSpec示例,ruby-on-rails,ruby,rspec,Ruby On Rails,Ruby,Rspec,我正在尝试添加一个函数,以便为未经身份验证的用户快速测试重定向。以下是我目前掌握的情况: def unauthenticated_redirects_to redirect_path #yeild context "when not signed in" do it "redirects to #{redirect_path}" do yield expect(response).to redirect_to redirect_path end
def unauthenticated_redirects_to redirect_path #yeild
context "when not signed in" do
it "redirects to #{redirect_path}" do
yield
expect(response).to redirect_to redirect_path
end
end
end
describe SomeController do
describe 'GET #show' do
unauthenticated_redirects_to('/some_path') { get :show }
context "when signed in" do
# One thing...
# Another thing...
end
end
describe 'GET #whatever' do
unauthenticated_redirects_to('/some_other_path') { get :whatever }
end
end
但是,这不起作用,因为主描述
块的范围和上下文对于传递到未经身份验证的\u重定向到
的块不可用。这合理地导致了错误:未定义RSpec::Core::ExampleGroup::Nested_1::Nested_2:Class的方法'get'
这是不是有办法,或者有一个更清洁的方法来完成类似的事情吗?我应该考虑一下。
P>看看。p> 考虑到我只关注一个例子,使用共享的例子似乎有些过分。此外,它的行为类似于(“未经验证的重定向到“,”/some\u other\u path',Proc.new{get:where})
似乎不必要地冗长。诀窍是使用#send()
来维护适当的范围
def unauthenticated_redirects_to path, method_action
context "when not signed in" do
it "redirects to #{path} for #{method_action}" do
send(method_action.first[0], method_action.first[1])
expect(response).to redirect_to path
end
end
end
describe 'GET #new' do
unauthenticated_redirects_to '/path', :get => :new
end
下面是一种使用共享示例的方法,它基于共享元数据触发示例(:auth=>true
,在本例中),并解析示例组描述以提取一些关键参数
require 'spec_helper'
class SomeController < ApplicationController
end
describe SomeController, type: :controller do
shared_examples_for :auth => true do
it "redirects when not signed in" do
metadata = example.metadata
description = metadata[:example_group][:description_args][0]
redirect_path = metadata[:failure_redirect]
http_verb = description.split[0].downcase.to_s
controller_method = description.match(/#(.*)$/)[1]
send(http_verb, controller_method)
expect(response).to redirect_to redirect_path
end
end
describe 'GET #show', :auth => true, :failure_redirect => '/some_path' do
context "when signed in" do
# One thing...
# Another thing...
end
end
describe 'GET #whatever', :auth => true, :failure_redirect => '/some_other_path' do
end
end
require'spec\u helper'
类SomeControllertrue do
它“未登录时重定向”是否执行
metadata=example.metadata
description=元数据[:示例组][:description\u args][0]
重定向\u路径=元数据[:失败\u重定向]
http\u verb=description.split[0]。downcase.to\s
controller_method=description.match(/#(.*)$/)[1]
发送(http\u动词、控制器\u方法)
expect(response)。重定向\u到重定向\u路径
结束
结束
描述'GET#show',:auth=>true,:failure\u redirect=>'/some\u path'do
上下文“登录时”do
#有一件事。。。
#还有一件事。。。
结束
结束
描述'GET#whatever',:auth=>true,:failure\u redirect=>'/some\u other\u path'do
结束
结束
为完整起见,下面是另一个共享示例方法,这次在调用前使用带的块参数,这避免了最初的范围问题:
require 'spec_helper'
class SomeController < ApplicationController
end
describe SomeController, type: :controller do
shared_examples_for 'auth ops' do
it "redirects when not signed in" do
expect(response).to redirect_to redirect_path
end
end
describe 'GET #show' do
it_behaves_like 'auth ops' do
let(:redirect_path) {'/some_path'}
before {get :show}
end
context "when signed in" do
# One thing...
# Another thing...
end
end
describe 'GET #new' do
it_behaves_like 'auth ops' do
let(:redirect_path) {'/some_other_path'}
before {get :whatever}
end
end
end
require'spec\u helper'
类SomeController
不确定为什么答案会消失,但这似乎是RSpec共享示例的一个很好的应用程序。你看过了吗?@PeterAlfvin我看过,但用例似乎不匹配。经过深思熟虑,我想出了办法。看看下面我添加的两个答案。我不知道元数据方法。我不太清楚为什么之前的方法不存在范围问题,但它没有。我确信共享示例完全适合您的情况。我在我的项目中使用的是完全相同的情况