can't go over the problem with CREATING INDEX ROUTE TEST for nested attribute. I've been trying all my ideas but nothing works
I have Service model and ServiceRoute model.
ServiceRoute belongs_to Service
and
Service has_many ServiceRoutes.
Here is my 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
I create ServiceRoute with build method
My routes.rb file:
resources :services do
resources :service_routes
end
Test "should create service route" has an error:
ActionController::UrlGenerationError: No route matches {:action=>"index", :controller=>"service_routes"} missing required keys: [: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
How should I refactor this test to match the route: /services/:service_id/service_routes
Testing nested routes may bring some confusion with regards to where the tests should be placed. Although nesting may give you the feeling the tests for the children should be written inside of the parent's tests, in fact they should be isolated in their own Test Case.
Rspec infers the controller being tested using the Test Case class name. You can also indicate it using a class method .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+.
Although you might be tempted to use the path as the first argument to the method .post, TestCase expects an action name such as :index, :create, :update and so on. The correct syntax for your test should be:
post :create, params: {
service_id: @service_route.service_id,
service_route: {
routes_list: @service_route.routes_list
}
}
Here's a snipet of the documentation for the 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' }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With