跳至内容 跳至搜索

一组断言用于测试由 Rails 生成的路由,以及对它们的请求处理。

命名空间
方法
A
M
W

实例公共方法

assert_generates(expected_path, options, defaults = {}, extras = {}, message = nil)

断言提供的选项可用于生成提供的路径。这是 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 204
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)

断言给定 path 的路由处理正确,并且解析的选项(在 expected_options 哈希中给出)与 path 匹配。基本上,它断言 Rails 识别由 expected_options 给出的路由。

在第二个参数 (path) 中传递一个哈希以指定请求方法。这对需要特定 HTTP 方法的路由很有用。哈希应该包含一个带有传入请求路径的 :path 和一个包含所需 HTTP 动词的 :method

# Asserts that POSTing to /items will call the create action on ItemsController
assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post})

您也可以用包含 URL 参数的哈希传递 extras,这些参数通常在查询字符串中。这可以用来断言查询字符串中的值将最终正确地出现在 params 哈希中。要测试查询字符串,您必须使用 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 164
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)

断言路径和选项在两个方向上都匹配;换句话说,它验证 path 生成 options,然后 options 生成 path。这实际上将 assert_recognizesassert_generates 合并为一个步骤。

extras 哈希允许您指定通常作为查询字符串提供给操作的选项。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 248
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, ...)

路由 TODO:这些断言应该在集成上下文中真正起作用

# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 261
def method_missing(selector, ...)
  if @controller && @routes&.named_routes&.route_defined?(selector)
    @controller.public_send(selector, ...)
  else
    super
  end
end

with_routing(config = nil, &block)

一个帮助程序,使测试不同的路由配置更加容易。此方法会暂时用新的 RouteSet 实例替换 @routes。

新实例将传递给传递的块。通常,块将使用 set.draw { match ... } 创建一些路由。

with_routing do |set|
  set.draw do
    resources :users
  end
  assert_equal "/users", users_path
end
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 121
def with_routing(config = nil, &block)
  old_routes, old_controller = @routes, @controller
  create_routes(config, &block)
ensure
  reset_routes(old_routes, old_controller)
end