所有四个 HTTP 谓词的自定义 RSpec 路由匹配器



我正在为一个相当大的 Rails 3 应用程序编写一个路由的 RSpec 测试套件。许多路线使用"MATCH",但没有一个应该,特别是因为我们在过渡到 Rails 4 时必须重写它们。

我的大多数it块看起来像这样:

  it "with /comments/account/100" do
    expect(get("comments/account/100")).to    route_to("comments#list", :account_id => "100")
    expect(post("comments/account/100")).to   route_to("comments#list", :account_id => "100")
    expect(put("comments/account/100")).to    route_to("comments#list", :account_id => "100")
    expect(delete("comments/account/100")).to route_to("comments#list", :account_id => "100")
  end

似乎有点,非 DRY,必须编写无穷无尽的块。我想要一个看起来像这样的匹配器:

expect(match_all_verbs("/comments/accounts/100")).to route_to("comments#list", :account_id => "100")

编辑:最终工作版本,感谢史蒂文:

def match_all_verbs(path, method, options = {})
  [:get, :post, :put, :delete].each do |verb|
    expect(send(verb, path)).to route_to(method, options)
  end
end

我添加了一个options哈希,以便我可以将参数传递给路由。一切似乎都正常。

为了好玩,我做了一个match_no_verbs来测试.to_not be_routable匹配器组合:

def match_no_verbs(path, method, options = {})
  [:get, :post, :put, :delete].each do |verb|
    expect(send(verb, path)).to_not route_to(method, options)
  end
end

非常感谢!

RSpec 自定义匹配器根据文档采用单个值,因此未定义形式参数values,并且在匹配器正文中对它的引用失败。

我认为您不想使用

自定义匹配器,其目的是指定相等的含义以及如何显示给定类型对象的错误,而是希望使用某种帮助程序来迭代谓词并生成适当的expect调用。

例如,您可以使用(未测试):

def match_all_verbs(path, method)
  [:get, :post, :put:, :delete].each do |verb|
    expect(send(verb, path)).to route_to(method)
  end
end

最新更新