ruby-on-rails - 嵌套资源的 Controller 测试

标签 ruby-on-rails ruby for-loop testing ruby-on-rails-5

无法解决嵌套属性的 CREATING INDEX ROUTE T​​EST 的问题。我一直在尝试我所有的想法,但没有任何效果

我有服务模型和服务路由模型。

ServiceRoute belongs_to Service

服务有_many ServiceRoutes。

这是我的 Controller :

class ServiceRoutesController < ApplicationController

before_action :set_service_route, only: [:show, :update, :destroy]
before_action :set_service, only: :create


def create
  @service_route = @service.service_routes.build(service_route_params)

  if @service_route.save
    render json: @service_route, status: :created, location: @service_route
  else
    render json: @service_route.errors, status: :unprocessable_entity
  end
end


private

  def set_service_route
    @service_route = ServiceRoute.find(params[:id])
  end

  def set_service
   @service = Service.find(params[:service_id])
  end

  def service_route_params
    params.require(:service_route).permit(:routes_list, :service_id)
  end
end

我使用构建方法创建 ServiceRoute

我的 routes.rb 文件:

resources :services do
  resources :service_routes
end

测试“should create service route”出错:

ActionController::UrlGenerationError:没有路由匹配 {:action=>"index", :controller=>"service_routes"} 缺少必需的键:[:service_id]

test "should create service_route" do
 assert_difference('ServiceRoute.count') do
  post service_service_routes_url, params: { service_route: {routes_list: 
  @service_route.routes_list, service_id: @service_route.service_id } }, 
 as: :json
end

我应该如何重构此测试以匹配路由:/services/:service_id/service_routes

最佳答案

测试嵌套路由可能会给测试应该放在哪里带来一些困惑。尽管嵌套可能会给您一种感觉,子级测试应该写在父级测试中,但实际上它们应该被隔离在自己的测试用例中。

Rspec 使用测试用例类名称推断正在测试的 Controller 。您还可以使用类方法 .tests 来指示它。

ActionController::TestCase will automatically infer the controller under test from the test class name. If the controller cannot be inferred from the test class name, you can explicitly set it with +tests+.

尽管您可能想将路径用作方法 .post 的第一个参数,但 TestCase 需要一个操作名称,例如 :index, :create, :update 等等。测试的正确语法应该是:

post :create, params: {
  service_id: @service_route.service_id,
  service_route: {
      routes_list: @service_route.routes_list 
    }
  }

这是 TestCase.get 的文档片段。

  # Simulate a GET request with the given parameters.
  #
  # - +action+: The controller action to call.
  # - +params+: The hash with HTTP parameters that you want to pass. This may be +nil+.
  # - +body+: The request body with a string that is appropriately encoded
  #   (<tt>application/x-www-form-urlencoded</tt> or <tt>multipart/form-data</tt>).
  # - +session+: A hash of parameters to store in the session. This may be +nil+.
  # - +flash+: A hash of parameters to store in the flash. This may be +nil+.
  #
  # You can also simulate POST, PATCH, PUT, DELETE, and HEAD requests with
  # +post+, +patch+, +put+, +delete+, and +head+.
  # Example sending parameters, session and setting a flash message:
  #
  #   get :show,
  #     params: { id: 7 },
  #     session: { user_id: 1 },
  #     flash: { notice: 'This is flash message' }

关于ruby-on-rails - 嵌套资源的 Controller 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43660689/

相关文章:

ruby-on-rails - 如何按散列值在 JSON 散列数组中进行搜索?

javascript - 字符串上的正则表达式或 For 循环 - 拆分和连接

php - for inside for loop php不适用于两个表

ruby-on-rails - 使用 PostgreSQL 在多列中进行全文搜索

ruby-on-rails - 从 ruby​​/rails 中的数组中加权随机选择

ruby-on-rails - 如何过滤每个模型名称 ruby​​ on rails 的记录数组

ruby-on-rails - 如何简化我的模型代码?

ruby-on-rails - Metal 与 Rack 有何不同?

python - 使用if语句修改行值

ruby-on-rails - Rails 5 参数/强参数问题