Reputation: 598
This application is a Rails 4 app and just an API (at this point). I can hit my URL from the browser, but when I try to access it in a test it can't find the URL. I get this:
No route matches {:action=>"/api/v1/users/20", :controller=>"api/v1/users"}
There are not any assertions in my test yet. Just trying to get past this error first:
# /spec/controllers/api/v1/users_controller_spec.rb
require 'rails_helper'
RSpec.describe Api::V1::UsersController, :type => :controller do
describe "User API" do
it "can return a user by ID" do
user = FactoryGirl.create(:user)
get "/api/v1/users/#{user.id}"
end
end
end
And my controller:
# app/controllers/api/v1/users_controller.rb
class Api::V1::UsersController < ApplicationController
before_action :set_user, only: [:show]
def show
end
private
def set_user
@user = User.find(params[:id])
end
end
Any my routes:
# config/routes.rb
Rails.application.routes.draw do
namespace :api, defaults: {format: 'json'} do
namespace :v1 do
resources :users, only: [:show]
end
end
end
And rake routes
give me:
Prefix Verb URI Pattern Controller#Action
api_v1_user GET /api/v1/users/:id(.:format) api/v1/users#show {:format=>"json"}
And my gems:
group :test do
gem 'capybara'
end
group :development, :test do
gem 'rspec-rails'
gem 'factory_girl_rails'
gem 'database_cleaner'
end
I'm sure there is something simple I am missing here, but I've spent a couple hours and can't figure it out.
Upvotes: 1
Views: 1073
Reputation: 598
I think I finally figured this out... to some extent. I think because this is a unit test, I need to pass get
the action name instead of the URL. Now I have this and it is working:
RSpec.describe Api::V1::UsersController, :type => :controller do
describe "User API" do
it "can return a user by ID" do
user = FactoryGirl.create(:user)
# get "/api/v1/users/#{user.id}" # This failed.
get :show, id: user.id, format: 'json' # This works!
end
end
end
I do want to test to make sure that URL's are not changing. I guess that's more like an integration test, so I think I'll probably do that in the features
directory and do it the way that @NickM mentioned.
I'm writing an API app. After fixing the above I was getting a missing template
error. I had to change my get
method to also have a format parameter.
Upvotes: 0
Reputation: 6942
You could try using Capybara's visit method instead of get. In /spec/controllers/api/v1/users_controller_spec.rb
require 'rails_helper'
require 'capybara' # unless you're already doing this in spec_helper.rb
RSpec.describe Api::V1::UsersController, :type => :controller do
describe "User API" do
it "can return a user by ID" do
user = FactoryGirl.create(:user)
visit "/api/v1/users/#{user.id}"
end
end
end
Upvotes: 1