在routes.rb中测试自定义重定向路由的Rails3 RSpec测试

4

我在routes.rb中设置了一个自定义重定向,它在用户界面上运行良好:

match ':hash' => redirect { |params| begin url = Sharing.find_by_short_url(params[:hash]); "/#{url.shareable_type}/#{url.shareable_id}/" rescue '/' end }, :constraints => { :hash => /[a-zA-Z0-9]{7}/ }

它的作用是获取缩短的URL并查找实际的URL路径。
然而,我的测试失败了:
  it "routes GET 'STU1VWX' to stations/1" do
    { :get => "STU1VWX" }.should redirect_to(
      :controller => "stations",
      :action => "show",
      :params => {:id => 1}
    )
  end

随着:

  1) Shorter URL redirect routes GET 'STU1VWX' to stations/1
     Failure/Error: { :get => "STU1VWX" }.should route_to(
     ActionController::RoutingError:
       No route matches "/STU1VWX"
     # ./spec/routing_spec.rb:12:in `block (2 levels) in <top (required)>'

所以问题在测试层面被隔离出来。我知道我可以在控制器测试中测试这个问题,但是考虑到代码在routes.rb中,我不应该这样做。在重定向的情况下,使用"should route_to"无法工作的本质原因是什么?


你试过用match '/:hash'代替match ':hash'吗? - iblue
你不应该在路由中执行ActiveRecord查询... - bodacious
我认为这是因为你无法在路由规范中测试重定向。您需要使用请求规范进行测试。这已经作为问题提交给rspec-rails,但已关闭:https://github.com/rspec/rspec-rails/issues/416。 - Andrew Ferk
1个回答

0

看起来你在这里说,如果找不到属于哈希的页面,那么就重定向到“/”

在路由中执行ActiveRecord查找似乎有些可疑。

如果你必须根据可共享类型重定向到特定控制器,那么我会将其作为一个单独的控制器,并进行重定向:

match "/:hash" => 'SharableController#redirect':constraints => { :hash => /[a-zA-Z0-9]{7}/ }

然后处理查找记录并从那里重定向到正确的控制器操作:

class SharableController < ApplicationController

  def redirect
    @sharable = Sharable.find_by_sharable_type(params[:hash])
    redirect_to controller: @sharable.sharable_type, action: 'show', id: @sharable.id
  end

end

或者...根据展示行为的相似程度而定:

class SharableController < ApplicationController

  def redirect
    @sharable = Sharable.find_by_sharable_type(params[:hash])
    render template: "#{@sharable.sharable_type.pluralize}/show"
  end

end

如果你只处理GET请求,最好顺便将match替换为get:

get "/:hash" => 'SharableController#redirect', :constraints => { :hash => /[a-zA-Z0-9]{7}/ }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接