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我看过,但用例似乎不匹配。经过深思熟虑,我想出了办法。看看下面我添加的两个答案。我不知道元数据方法。我不太清楚为什么
之前的
方法不存在范围问题,但它没有。我确信共享示例完全适合您的情况。我在我的项目中使用的是完全相同的情况