如何使用 rspec 测试路由约束

2023-12-23

我正在开发一个主要用作 API 的应用程序(除了一些次要视图,例如会话/注册,这将是“标准”)。我喜欢最终确定的方法Railscast #350:API 版本控制 http://railscasts.com/episodes/350-rest-api-versioning,于是也跟着做了。我的路线如下:

namespace :api, :defaults => {:format => 'json'} do
  scope :module => :v1, :constraints => ApiConstraints.new(:version => 1, :default => false) do
    resources :posts, :only => [:create, :show, :destroy, :index]
  end

  scope :module => :v2, :constraints => ApiConstraints.new(:version => 2, :default => true) do
    resources :posts, :only => [:create, :show, :destroy, :index]
  end
end

在每个路由中,我的 Constraint 是一个新的 ApiConstraints 对象,它位于我的./lib文件夹。该类看起来像这样:

class ApiConstraints
  def initialize(options)
    @version = options[:version]
    @default = options[:default]
  end

  def matches?(req)
    @default || req.headers['Accept'].include?("application/vnd.MYAPP.v#{@version}")
  end
end

现在,当手动测试时,一切都按预期进行。在我的 API 中,每个版本可能有 5 到 10 个控制器,并且不想测试 API 约束是否适用于每个单独的控制器,因为这没有意义。我正在寻找一个测试我的 API 约束的规范文件,但我不确定将该规范放在哪里。

我试过添加一个spec/routing/api_spec.rb文件来测试事物,但它无法正常工作,因为它抱怨未提供某些内容,如下所示:

it "should route an unversioned request to the latest version" do
  expect(:get => "/api/posts", :format => "json").to route_to(:controller => "api/v1/posts")
end

即使控制器正确匹配,上面的代码也会抛出错误。它失败并出现以下错误:

The recognized options <{"format"=>"json", "action"=>"index", "controller"=>"api/v1/posts"}>
did not match <{"controller"=>"api/v1/posts"}>,
difference: <{"format"=>"json", "action"=>"index"}>.

请注意,控制器已正确确定,但由于我不想在此测试中测试格式和操作,因此会出错。我希望有 3 个“API 规范”:

  • 它应该将未版本控制的请求路由到最新版本
  • 如果未指定,则默认为 JSON 格式
  • 它应该在请求时返回指定的 API 版本

有人有为此类路线编写规范的经验吗?我不想为 API 内的每个控制器添加规范,因为它们不负责此功能。


Rspec's route_to匹配器代表ActionDispatch::Assertions::RoutingAssertions#assert_recognizes http://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html#method-i-assert_recognizes

论点为route_to被传递为expected_options哈希(经过一些预处理后,它还可以理解速记样式的参数,例如items#index).

您期望匹配的哈希值route_to匹配器(即{:get => "/api/posts", :format => "json"})实际上并不是一个格式良好的论证expect。如果你看来源 https://github.com/rspec/rspec-rails/blob/master/lib/rspec/rails/matchers/routing_matchers.rb,你可以看到我们得到了匹配的路径 via

path, query = *verb_to_path_map.values.first.split('?')

The #first这是一个明确的信号,表明我们期望得到一个只有一个键值对的哈希值。所以:format => "json"组件实际上只是被丢弃,并且没有做任何事情。

The ActionDispatch断言期望您将完整的路径+动词与一组完整的控制器、操作和路径参数相匹配。所以 rspec 匹配器只是传递它委托的方法的限制。

听起来像是 rspec 内置的route_tomatcher 不会做你想做的事。所以下一个建议是假设ActionDispatch会做它应该做的事情,而只是为你的产品编写规范ApiConstraints class.

为此,我首先建议not使用默认值spec_helper。科里·海恩斯(Corey Haines)有一个很好的要点如何制作一个更快的规范助手,并且不会启动整个 Rails 应用程序 https://gist.github.com/coreyhaines/2068977。它可能并不适合您的情况,但我只是想指出这一点,因为您只是在这里实例化基本的 ruby​​ 对象,并且实际上并不需要任何 Rails 魔法。您也可以尝试要求ActionDispatch::Request& 依赖项,如果您不想像我在这里那样删除请求对象。

那看起来像

spec/lib/api_constraint.rb

require 'active_record_spec_helper'
require_relative '../../lib/api_constraint'

describe ApiConstraint do

  describe "#matches?" do

    let(:req) { Object.new }

     context "default version" do

       before :each do
         req.stub(:headers).and_return {}
         @opts = { :version => nil, :default => true }
       end

       it "returns true regardless of version number" do
         ApiConstraint.new(@opts).should match req
       end

     end

  end

end

...aa并且我会让您准确地弄清楚如何设置上下文/编写其他测试的期望。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 rspec 测试路由约束 的相关文章

  • 在 Heroku 上托管的 Rails3 中强制使用“www”,无需 .htaccess

    我想知道是否有 Rack 替代方案来强制 URL 中包含 www 因为 Heroku 不使用 htaccess 文件 也许甚至是在路线中做到这一点的好方法 Thanks 在您的 ApplicationController 中 您可以简单地创
  • 如何在 PostgreSQL 中使用条件和子查询创建唯一索引?

    我使用 PGSQL 并尝试添加下面的索引 CREATE UNIQUE INDEX fk client ON user client fk client WHERE fk client NOT IN SELECT fk client FROM
  • 我在 Rails 中使用了保留字吗?

    这是我的模型 class Record lt ActiveRecord Base belongs to user belongs to directory end class Directory lt ActiveRecord Base h
  • 浏览器关闭时 Omniauth 会话过期

    在我的 Rails 3 应用程序中 我使用 Omniauth 进行用户身份验证部分 fb twitter 实际上我遵循这个 https github com RailsApps rails3 mongoid omniauth https g
  • 在 Rails 3 中渲染 Markdown 文本

    我想将 markdown 转换为 html 在我看来我有markdown some text variable 但我得到了错误undefined method markdown I added require BlueCoth 到envir
  • 即使在急切加载之后,belongs_to 关联也会单独加载

    我有以下关联 class Picture lt ActiveRecord Base belongs to user end class User lt ActiveRecord Base has many pictures end 在我的
  • Rails 4 应用程序...在开发环境中,除非刷新页面,否则 javascript 不会触发

    所以我的第一个rails4应用程序遇到了一个奇怪的问题 除非我重新加载页面 否则我的页面javascript不会触发 对于我的 asset pipeline JS 和 content for JS 来说都是如此 在我的 assets jav
  • Windows 7 x64 上的 Ruby on Rails SQLite 问题

    当我尝试做的时候db create使用 Windows 7 x64 在具有此数据库配置的 sqlite 数据库上 development adapter sqlite3 database db development sqlite3 tim
  • Rails Windows Vagrant 响应时间非常慢

    我在跑 Vagrant 1 7 1 Rails 4 1 4 Thin 1 6 1 Windows 7 每个静态文件的发送时间都超过一秒 在我的 PC 上加载一个页面可能需要大约 20 秒 而在同事的 Linux 机器上则只需瞬间 有一些帖子
  • 来自控制器的 Rails 验证

    有一个联系页面 可以输入姓名 电话 电子邮件和消息 然后发送到管理员的电子邮件 没有理由将消息存储在数据库中 问题 如何 在控制器中使用 Rails 验证 根本不使用模型 或者 在模型中使用验证 但没有任何数据库关系 UPD Model c
  • Ruby/Rails 集合到集合

    我有两个表与一个连接表连接 这只是伪代码 Library Book LibraryBooks 我需要做的是 如果我有一个图书馆的 id 我想获取该图书馆拥有的所有书籍所在的所有图书馆 因此 如果我有图书馆 1 图书馆 1 中有书籍 A 和
  • Shoulda/RSpec 匹配器 - 条件验证

    在我的代码中 我使用 Shoulda 匹配器进行了以下验证 效果很好 it should validate presence of name 在我的模型中 我已将条件添加到验证中 validates presence of name if
  • Ruby on Rails 服务器在 HTTPS POST 请求期间崩溃

    我正在尝试与你沟通城市飞艇API http urbanairship com docs push html broadcast使用 ROR Web 应用程序 在我的控制器中 我有以下代码 require net http require n
  • 让 Rails 生产在端口 80 上运行

    我正在尝试让我的 Rails 应用程序在生产模式下运行 但遇到了一些困难 我正在使用 Passenger 和 apache 并运行 Ubuntu 12 04 我已经配置和创建了生产数据库 并设置了乘客 状态如下 rvmsudo passen
  • Rails 中的嵌套布局

    Rails 3 2 中可以嵌套布局吗 我想创建 application html erb 使用的通用布局 并允许应用程序中的几个视图使用它 我找到了嵌套布局 https github com eric nested layoutsruby
  • 即使路由存在,Rspec 命名空间路由规范也会失败

    我在用着rspec rails 2 8 1 and 导轨3 1 3 我正在尝试测试 Admin ZonesController 的路由 我已经通过运行验证了浏览器中存在该路由rake routes 我没有使用 ActiveRecord 如果
  • Rails 3.2:用 json 序列化中的空字符串替换 null 值

    我正在使用 Rails 3 2序列化 http www simonecarletti com blog 2010 04 inside ruby on rails serializing ruby objects with json 将 ru
  • Travis-CI 上的 Rails 数据库设置

    我正在尝试在 Rails 项目上使用 Travis 持续集成 文档说 对于 SQLite3 测试数据库必须配置如下 test adapter sqlite3 database memory timeout 500 但我想保留本地测试的默认配
  • Rails 中的字母分页

    我正在寻找 Rails 的宝石用于字母分页 我希望我可以在结果中找到第一个字母的列表 我的意思是 如果没有以 a 开头的行 我不希望 a 显示在分页链接上 这种宝石已经存在了吗 提前致谢 这根本不难创建 例如 如果您有一个find 也许像
  • rake db 问题:迁移 -

    我无法为 Ruby on Rails 设置 MySQL 数据库 设置数据库并确保 config database yml 文件匹配后 我遇到了以下错误消息 U Rails alpha gt rake db migrate trace in

随机推荐

  • 通过 ASP.NET 菜单控件禁用 javascript 生成

    在我的网站中 我使用标准 ASP NET 菜单控件 我已经编写了一个自定义控制适配器来摆脱由默认控制适配器生成的相当俗气的 html 输出 但有一件事一直困扰着我 不知何故 ASP NET 生成了我的菜单控件不需要的额外 JavaScrip
  • Google 地理编码 API 错误:超出查询限制。 - 导轨

    我知道有人问过这个问题 但大多数答案都是几年前的 而且并非全部针对 Ruby on Rails 项目 在我当前的项目中 我使用 Geocode gem 通过 Ruby on Rails 任何人都可以按用户的位置搜索用户 我还使用 Carme
  • 使用ggplot、gtable和cowplot固定图例框的宽度

    我想用 R 制作一个绘图 看起来像用 Mac 的 Numbers 制作的示例 我正在努力处理情节和图例框之间的空间 这是我想要实现的目标的示例 在一些用户的帮助下 请参阅帖子末尾以供参考 我已经非常接近了 这是我当前的功能 library
  • 在 Javascript 中实现后退按钮“警告”以在 Flex 中使用

    我有一个 Flex 应用程序 如果用户按下后退按钮 我想向他们发出警告 这样他们就不会错误地离开该应用程序 我知道由于跨浏览器不兼容 这不能完全在 Actionscript 中完成 我正在寻找的只是捕获后退按钮的 Javascript 实现
  • 带有 Node.js 和 Express 的基本网络服务器,用于提供 html 文件和资产

    我正在做一些前端实验 我想要一个非常基本的网络服务器来快速启动一个项目并提供文件 一个index html文件 一些css js img文件 所以我试图用node js和express做一些东西 我已经玩过了 但这次我不想使用渲染引擎 因为
  • 是否有可能拥有 JSON.stringify 保留功能?

    拿这个对象 x key1 xxx key2 function return this key1 如果我这样做 y JSON parse JSON stringify x 然后 y 将返回 key1 xxx 有什么办法可以通过 stringi
  • 在 Matlab 中创建二进制矩阵,报告数量不断增加

    我希望你建议编写一个创建二进制矩阵的 Matlab 代码A尺寸的31x5这样 第一行A is 1 1 1 1 1 从2号到6号A我们有1每行仅一次 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0
  • 如何更改android模拟器的日期?

    我需要更改模拟器的日期 你该怎么做 我尝试了开发设置 但他们不让我编辑它 我刚刚尝试过 像在任何其他 Android 设备上一样更改它 打开正常设置 不是开发 并转到日期和时间 取消选中 自动日期和时间 并在下面设置所需的日期
  • 运行时的 Java 编译器

    在我当前的项目中 我需要在运行时编译java代码 在后台处理用户的输入 这与类路径中的tools jar 配合得很好 但是 并非我的程序的所有用户都在其系统上安装了 JDK 其中一些只有 JRE 在这种情况下 运行时没有可用的 java 编
  • 使用Holoviews,如何设置标题?

    我一直在尝试在使用 Holoviews 和 Bokeh 时设置标题 我将 3 个图相互叠加 代码如下所示 opts Curve width 900 height 400 show grid True tools hover finalize
  • 如何删除 d3.behavior.drag().on("drag",...) 事件处理程序[重复]

    这个问题在这里已经有答案了 我将以下内容附加到 svg 元素 var dragger d3 behavior drag origin function d return d on drag this move on dragend drop
  • 选择要从中选择的表,取决于已给定表的列值

    为了我的目的 我必须选择一个表来根据已给定表的列值选择列 首先 我考虑了 CASE 构造 如果 sqlite 可以实现的话 SELECT FROM CASE IF myTable column1 value1 THEN SELECT FRO
  • 如何获取可执行文件的版本?

    萨尔维特 我正在编写一个 vb net 程序来更新我的应用程序的自述文件 我想从其他编译的应用程序中提取版本号 我想从可执行文件中读取版本号 而不是从其未编译的资源中读取版本号 如何在 vb net 中执行此操作而不使用像 reshacke
  • 除了锁定的对象之外,我还可以将对象更改保存到另一个 TR 中吗?

    当我尝试切换到报告源的编辑模式时 会出现一个弹出窗口告诉我 将为用户XXX的以下请求创建一个新任务 还提出了运输请求 但是 我不想在此请求中保存我的更改 而是在另一个现有请求中保存更改 我不知道我的系统中正在实施任何版本控制系统 也不知道如
  • iOS ClipsToBounds YES 和 Shadow?

    我有一个浮动的 UITableView 有圆角和设定的高度 但我也想添加阴影 但我的问题是我需要clipsToBounds打开 这样我的单元格就不会超出浮动的 UITableView 是否有办法在为 UITableView 保持 Clips
  • 使用 androidx DialogFragment 创建 AlertDialog 时按钮样式错误

    这是我的根风格
  • Firefox 3 书签中的 Http Auth

    我正在尝试创建一个书签 用于将 del icio us 书签发布到单独的帐户 我从命令行测试了它 例如 wget O no check certificate https seconduser email protected cdn cgi
  • 如何将 Jaeger 与 Spring WebFlux 结合使用?

    我们正在尝试与 Webflux 进行反应 我们将 Jaegar 与 Istio 结合使用来实现检测目的 Jaeger 很好地理解 Spring MVC 端点 但似乎根本不适用于 WebFlux 我正在寻找让我的 webflux 端点出现在
  • 将变量传递给 R 中的 WinBugs 模型

    我正在使用 R2WinBugs 包 我想将之前在 R 脚本中计算的两个参数传递给模型函数 c0yy lt 0 1 syy lt 0 0001 Model model lt function c0yy syy Likelihood for i
  • 如何使用 rspec 测试路由约束

    我正在开发一个主要用作 API 的应用程序 除了一些次要视图 例如会话 注册 这将是 标准 我喜欢最终确定的方法Railscast 350 API 版本控制 http railscasts com episodes 350 rest api