1

我正在尝试添加一个功能,以允许快速测试未经身份验证的用户的重定向。这是我到目前为止所拥有的:

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

但是,这不起作用,因为主describe块的范围和上下文对于传递给unauthenticated_redirects_to. 这合理地导致了错误:undefined method `get' for RSpec::Core::ExampleGroup::Nested_1::Nested_2:Class.

有没有办法解决这个问题,或者有没有更清洁的方法来完成我应该考虑的类似事情?

4

4 回答 4

0

看看rspec 共享示例

于 2013-08-22T20:51:15.037 回答
0

考虑到我只关心一个例子,使用shared_examples_for似乎有点过头了。此外,it_behaves_like("unauthenticated redirects to", '/some_other_path', Proc.new{ get :whatever})似乎不必要地冗长。诀窍是用来#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
于 2013-09-05T19:02:04.093 回答
0

这是一种使用共享示例的方法,它基于共享元数据(: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
于 2013-09-05T21:45:09.693 回答
0

为了完整起见,这是另一种共享示例方法,这次使用带有before调用的块参数来避免原始范围问题:

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
于 2013-09-05T22:01:26.153 回答