用于测试 Rails 生成的路由以及路由处理请求的断言集合。
- MODULE ActionDispatch::Assertions::RoutingAssertions::ClassMethods
- MODULE ActionDispatch::Assertions::RoutingAssertions::WithIntegrationRouting
实例公共方法
assert_generates(expected_path, options, defaults = {}, extras = {}, message = nil) Link
断言提供的选项可用于生成提供的路径。这是 assert_recognizes 的反向操作。extras 参数用于告知请求查询字符串中存在的其他请求参数的名称和值。message 参数允许您为断言失败指定自定义错误消息。
defaults 参数未使用。
# Asserts that the default action is generated for a route with no action assert_generates "/items", controller: "items", action: "index" # Tests that the list action is properly routed assert_generates "/items/list", controller: "items", action: "list" # Tests the generation of a route with a parameter assert_generates "/items/list/1", { controller: "items", action: "list", id: "1" } # Asserts that the generated route gives us our custom route assert_generates "changesets/12", { controller: 'scm', action: 'show_diff', revision: "12" }
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 216 def assert_generates(expected_path, options, defaults = {}, extras = {}, message = nil) if expected_path.include?("://") fail_on(URI::InvalidURIError, message) do uri = URI.parse(expected_path) expected_path = uri.path.to_s.empty? ? "/" : uri.path end else expected_path = "/#{expected_path}" unless expected_path.start_with?("/") end options = options.clone generated_path, query_string_keys = @routes.generate_extras(options, defaults) found_extras = options.reject { |k, _| ! query_string_keys.include? k } msg = message || sprintf("found extras <%s>, not <%s>", found_extras, extras) assert_equal(extras, found_extras, msg) msg = message || sprintf("The generated path <%s> did not match <%s>", generated_path, expected_path) assert_equal(expected_path, generated_path, msg) end
assert_recognizes(expected_options, path, extras = {}, msg = nil) Link
断言给定的 path 的路由已正确处理,并且解析的选项(在 expected_options hash 中给出)与 path 匹配。基本上,它断言 Rails 识别由 expected_options 给出的路由。
在第二个参数(path)中传递一个 hash 来指定请求方法。这对于需要特定 HTTP 方法的路由很有用。该 hash 应包含一个 :path(请求的传入路径)和一个 :method(必需的 HTTP 动词)。
# Asserts that POSTing to /items will call the create action on ItemsController assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post})
您还可以通过 extras 传递一个 hash,其中包含通常会在查询字符串中出现的 URL 参数。这可用于断言查询字符串中的值是否正确地包含在 params hash 中。要测试查询字符串,您必须使用 extras 参数,因为直接在路径中附加查询字符串将不起作用。例如
# Asserts that a path of '/items/list/1?view=print' returns the correct options assert_recognizes({controller: 'items', action: 'list', id: '1', view: 'print'}, 'items/list/1', { view: "print" })
message 参数允许您传递一个在失败时显示的错误消息。
# Check the default route (i.e., the index action) assert_recognizes({controller: 'items', action: 'index'}, 'items') # Test a specific action assert_recognizes({controller: 'items', action: 'list'}, 'items/list') # Test an action with a parameter assert_recognizes({controller: 'items', action: 'destroy', id: '1'}, 'items/destroy/1') # Test a custom route assert_recognizes({controller: 'items', action: 'show', id: '1'}, 'view/item1')
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 176 def assert_recognizes(expected_options, path, extras = {}, msg = nil) if path.is_a?(Hash) && path[:method].to_s == "all" [:get, :post, :put, :delete].each do |method| assert_recognizes(expected_options, path.merge(method: method), extras, msg) end else request = recognized_request_for(path, extras, msg) expected_options = expected_options.clone expected_options.stringify_keys! msg = message(msg, "") { sprintf("The recognized options <%s> did not match <%s>, difference:", request.path_parameters, expected_options) } assert_equal(expected_options, request.path_parameters, msg) end end
assert_routing(path, options, defaults = {}, extras = {}, message = nil) Link
断言路径和选项双向匹配;换句话说,它验证 path 生成 options,然后验证 options 生成 path。这实际上是将 assert_recognizes 和 assert_generates 结合在一起。
extras hash 允许您指定通常作为查询字符串提供给操作的选项。message 参数允许您指定一个自定义错误消息以在失败时显示。
# Asserts a basic route: a controller with the default action (index) assert_routing '/home', controller: 'home', action: 'index' # Test a route generated with a specific controller, action, and parameter (id) assert_routing '/entries/show/23', controller: 'entries', action: 'show', id: 23 # Asserts a basic route (controller + default action), with an error message if it fails assert_routing '/store', { controller: 'store', action: 'index' }, {}, {}, 'Route for store index not generated properly' # Tests a route, providing a defaults hash assert_routing 'controller/action/9', {id: "9", item: "square"}, {controller: "controller", action: "action"}, {}, {item: "square"} # Tests a route with an HTTP method assert_routing({ method: 'put', path: '/product/321' }, { controller: "product", action: "update", id: "321" })
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 260 def assert_routing(path, options, defaults = {}, extras = {}, message = nil) assert_recognizes(options, path, extras, message) controller, default_controller = options[:controller], defaults[:controller] if controller && controller.include?(?/) && default_controller && default_controller.include?(?/) options[:controller] = "/#{controller}" end generate_options = options.dup.delete_if { |k, _| defaults.key?(k) } assert_generates(path.is_a?(Hash) ? path[:path] : path, generate_options, defaults, extras, message) end
method_missing(selector, ...) Link
路由 TODO:这些断言应该真正地在集成上下文中工作
with_routing(config = nil, &block) Link
一个辅助方法,用于更轻松地测试不同的路由配置。此方法会临时用一个新的 RouteSet 实例替换 @routes。
新实例将被传递给块。通常,块会使用 set.draw { match ... } 创建一些路由
with_routing do |set| set.draw do resources :users end assert_equal "/users", users_path end