hello i'm doing some test of my application with Rspec (this is my very first time i'm using it)
this is my test file located in spec/controllers/recipes_controller_spec.rb:
require 'spec_helper'
describe RecipesController do
render_views
describe "index" do
before do
Recipe.create!(name: 'Baked Potato w/ Cheese')
Recipe.create!(name: 'Garlic Mashed Potatoes')
Recipe.create!(name: 'Potatoes Au Gratin')
Recipe.create!(name: 'Baked Brussel Sprouts')
xhr :get, :index, format: :json, keywords: keywords
end
subject(:results) { JSON.parse(response.body) }
def extract_name
->(object) { object["name"] }
end
context "when the search finds results" do
let(:keywords) { 'baked' }
it 'should 200' do
expect(response.status).to eq(200)
end
it 'should return two results' do
expect(results.size).to eq(2)
end
it "should include 'Baked Potato w/ Cheese'" do
expect(results.map(&extract_name)).to include('Baked Potato w/ Cheese')
end
it "should include 'Baked Brussel Sprouts'" do
expect(results.map(&extract_name)).to include('Baked Brussel Sprouts')
end
end
context "when the search doesn't find results" do
let(:keywords) { 'foo' }
it 'should return no results' do
expect(results.size).to eq(0)
end
end
end
end
when i try to execute it by the command:
bundle exec rspec spec/controllers/recipes_controller_spec.rb
i fail all my tests with this error:
Failure/Error: xhr :get, :index, format: :json, keywords: keywords
NameError:
uninitialized constant RecipesController::Recipes
# ./app/controllers/recipes_controller.rb:4:in `index'
# ./spec/controllers/recipes_controller_spec.rb:12:in `block (3 levels) in <top (required)>'
i've tried to look all my code but i haven't find out the error
NameError: uninitialized constant RecipesController::Recipes
means you used Recipes instead of Recipe somewhere (line 4 in index) in controller, and since your model is called Recipe (singular), you're getting NameError exception.
Related
I'm having problem with using rspec in ruby-on-rails app
my users_spec.rb
require 'rails_helper'
RSpec.describe 'Get /', type: :request do
it 'test / get method' do
expect(response).to have_http_status(:success)
expect(response).to include('index')
end
end
my routes.rb
Rails.application.routes.draw do
get "/" => "users#index"
end
my users_controller.rb
class UsersController < ApplicationController
def index
end
end
my index.erb
<h1>index</h1>
when I run "bundle exec rspec". , I get error like this
.F
Failures:
1) Get / test / get method
Failure/Error: expect(response).to have_http_status(:success)
expected the response to have a success status code (2xx) but it was
# ./spec/requests/users_spec.rb:5:in `block (2 levels) in <main>'
Finished in 0.11204 seconds (files took 5.18 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./spec/requests/users_spec.rb:4 # Get / test / get method
and I can't catch where is wrong..
Your spec is not correct. Your spec is not actually calling the endpoint. You need to add a get "/" call, that will actually call the endpoint
require 'rails_helper'
RSpec.describe 'Get /', type: :request do
it 'test / get method' do
get "/" #this is the missing line; this actually makes the request
expect(response).to have_http_status(:success)
expect(response).to include('index')
end
end
I am trying to write an rspec file for my meetings_controller.rb so as to check if the values returned from my database are correct.
When I go to localhost:3000/meeting.json, this is the result of my data from the database
my rspec file is trying to check if the correct values are returned.
I created a folder called controller under specs (after I have installed rspec)and have the file meeting_controller_spec.rb
require 'rails_helper'
# Change this ArticlesController to your project
RSpec.describe MeetingsController, type: :controller do
describe "GET #index" do
# check index
it "returns a success response" do
get :index
puts response.body
expect(response).to have_http_status(:ok)
end
end
end
I tried to print the response body but nothing is returning. Is there a way to do this?
(base) adam-a01:reservation adrianlee$ rspec
.
Finished in 0.0892 seconds (files took 12.15 seconds to load)
1 example, 0 failures
Btw this is my meeting_controller.rb
class MeetingsController < ApplicationController
before_action :set_meeting, only: [:show, :edit, :update, :destroy]
# GET /meetings
# GET /meetings.json
def index
#meetings = Meeting.all
#meeting = Meeting.new
end
end
Update: I also tried this method as suggested below but it didnt work still
# Change this ArticlesController to your project
RSpec.describe MeetingsController, type: :controller do
describe "GET #index" do
# check index
it "returns a success response" do
get :index
raise response.body
expect(response).to have_http_status(:ok)
end
end
end
This is the error raised
Failures:
1) MeetingsController GET #index returns a success response
Failure/Error: raise response.body
RuntimeError:
# ./spec/controllers/meeting_controller_spec.rb:10:in `block (3 levels) in <top (required)>'
If you are trying to get this value for a debugging purpose you should use byebug or pry gems.
If you choose byebug, add it to your gemfile gem 'byebug' on test environment.
run bundle install and after that you are able to use it on your tests
So replace the puts with byebug
describe "GET #index" do
# check index
it "returns a success response" do
get :index
byebug
expect(response).to have_http_status(:ok)
end
end
At the console now you are exactly there. Just type response.body and enter to print it's value.
When you are done, just type c and then enter to release the console e continue your tests.
Also check here for more information about debugging with byebug
In my case I do it like this:
require 'rails_helper'
describe SuppliersController, type: :controller do
describe 'GET /suppliers' do
let!(:access_token) { create :access_token }
let!(:admin_user_token) do
create :user_token, resource_owner: create(:admin_user)
end
context 'when the requester is an admin' do
it 'returns HTTP status 200 (OK)' do
allow(controller).to receive(:doorkeeper_token) { access_token }
#request.env['HTTP_X_USERTOKEN'] = admin_user_token.token
get :index
raise response.body.inspect ## Here is what prints the value in the console.
body = JSON.parse response.body
expect(response).to have_http_status :ok
expect(body['status']).to eq 'OK'
end
end
end
end
To run the test:
rspec spec/controllers/suppliers/suppliers_controller_index_spec.rb
And it gives me the output:
F
Failures:
1) SuppliersController GET /suppliers when the requester is an admin returns HTTP status 200 (OK)
Failure/Error: raise response.body.inspect
RuntimeError:
"{\"status\":\"OK\",\"message\":\"Your request has been processed successfully.\",\"data\":[],\"page\":{\"current_page\":1,\"prev_page\":null,\"next_page\":null,\"per_page\":25,\"total_pages\":0}}"
# ./spec/controllers/suppliers/suppliers_controller_index_spec.rb:17:in `block (4 levels) in <top (required)>'
Finished in 0.47594 seconds (files took 2.82 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/controllers/suppliers/suppliers_controller_index_spec.rb:11 # SuppliersController GET /suppliers when the requester is an admin returns HTTP status 200 (OK)
I have to say raise a runtime error to check variable value is not a good practice,maybe you should try gem 'pry' or gem 'byebug' suggested by #DR7.
Another thing you need make sure is did you run rails s and rspec in different environment?This maybe lead to they connect to separate db.
I'm following this tutorial for a rails API but it is a little outdated and some things don't seem to work with newer versions of rails. I'm having a hard time with the user controller specs:
user_controller_spec.rb
require 'rails_helper'
RSpec.describe Api::V1::UsersController, type: :controller do
describe "GET #show" do
before(:each) do
#user = FactoryGirl.create :user
get :show, params: {id: #user.id}
end
it "returns the information about a reporter on a hash" do
user_response = JSON.parse(response.body, symbolize_name: true)
expect(user_response[:email]).to eql #user.email
end
it { expect(response).to have_http_status(200) }
end
end
user_controller.rb
class Api::V1::UsersController < ApplicationController
def show
render json: User.find(params[:id])
end
end
user.rb factory
FactoryGirl.define do
factory :user do
email { FFaker::Internet.email }
password "12345678"
password_confirmation "12345678"
end
end
But, this isn't working, the email doesn't seem to match. Any ideas what could be wrong?
Failures:
1) Api::V1::UsersController GET #show returns the information about a reporter on a hash
Failure/Error: expect(user_response[:email]).to eql #user.email
expected: "mitzie_nikolaus#rice.com"
got: nil
(compared using eql?)
# ./spec/controllers/api/v1/users_controller_spec.rb:12:in `block (3 levels) in <top (required)>'
The code is correct, but you've made a typo in using the symbolize_names option for JSON.parse.
I assume, that because you do not copy-paste examples, but type it by your own, which is great, because it's better for learning.
To fix the test just correct this line (change symbolize_name to symbolize_names):
user_response = JSON.parse(response.body, symbolize_names: true)
This is my Spec file:
require 'rails_helper'
RSpec.describe Programmes::ReportsController, :type => :controller do
let!(:programme) { create(:programme) }
context 'authenticated user' do
describe 'GET index' do
it 'responds with a 200 OK status code' do
get :index, params: { id: programme.id }
expect(response).to have_http_status(:success)
end
end
end
end
This is my Factory;
FactoryGirl.define do
factory :programme do
name { Faker::Lorem.word }
description { Faker::Lorem.sentence(3) }
end
end
This is my Controller;
class Programmes::ReportsController < ApplicationController
def index
end
def create
end
end
I can't seem to get this spec to pass. The route works fine in the browser; eg
http://localhost:3000/programmes/{:id}/reports
The error I have is:
Failures:
1) Programmes::ReportsController authenticated user GET index responds with a 200 OK status code
Failure/Error: let!(:programme) { create(:programme) }
NoMethodError:
undefined method `create' for #<RSpec::ExampleGroups::ProgrammesReportsController::AuthenticatedUser::GETIndex:0x007fac78b1b440>
# /Users/mike/.rvm/gems/ruby-2.2.3/gems/actionpack-5.0.0/lib/action_dispatch/testing/assertions/routing.rb:172:in `method_missing'
I am quite new to Ruby (and Rails). I don't think the Programme object is being created in FactoryGirl - but I don't really know how to find out if that's the case
Did you require 'factory_girl' in spec_helper?
I am doing some simple integration testing. I want to test the sold_items action in the users controller. I have confirmed that the route exists and returns json by accessing it from the browser. However, rspec is telling me that the route doesn't exist. PLease see below, the spec, the error, and my route.rb. Thanks!
spec:
require 'rails_helper'
RSpec.describe UsersController, type: :controller do
describe "GET #items" do
it "returns http success" do
user = FactoryGirl.create(:user)
get "users/#{user.id}/sold_items"
expect(response).to have_http_status(:success)
end
end
end
fail message:
1) UsersController GET #items returns http success
Failure/Error: get "users/#{user.id}/sold_items"
ActionController::UrlGenerationError:
No route matches {:action=>"users/10/sold_items", :controller=>"users"}
# ./spec/controllers/users_controller_spec.rb:8:in `block (3 levels) in <top (required)>'
routes.rb
Rails.application.routes.draw do
resources :users
resources :items
get "users/:id/sold_items" => "users#sold_items"
EDIT
spec
require 'rails_helper'
RSpec.describe UsersController, type: :controller do
describe "GET #items" do
it "returns http success" do
user = FactoryGirl.create(:user)
get "users/:id/sold_items", id: user.id
expect(response).to have_http_status(:success)
end
end
end
failure message
2) UsersController GET #items returns http success
Failure/Error: get "users/:id/sold_items", id: user.id
ActionController::UrlGenerationError:
No route matches {:action=>"users/:id/sold_items", :controller=>"users", :id=>"12"}
# ./spec/controllers/users_controller_spec.rb:8:in `block (3 levels) in <top (required)>'
EDIT.2 MarvC second suggestion
require 'rails_helper'
RSpec.describe UsersController, type: [:request, :controller] do
describe "GET #items" do
it "returns http success" do
user = FactoryGirl.create(:user)
get "/users/:id/sold_items", id: user.id
expect(response).to have_http_status(:success)
end
end
end
failure
looks like the user.id isn't being passed in properly here
2) UsersController GET #items returns http success
Failure/Error: #sold_items = User.find(params[:id]).seller_items.sold
ActiveRecord::RecordNotFound:
Couldn't find User with 'id'=:id
# ./app/controllers/users_controller.rb:6:in `sold_items'
# ./spec/controllers/users_controller_spec.rb:8:in `block (3 levels) in <top (required)>'
One Solution:
when I use string interpolation to pass user.id into the url it works...
require 'rails_helper'
RSpec.describe UsersController, type: [:request, :controller] do
describe "GET #items" do
it "returns http success" do
user = FactoryGirl.create(:user)
get "users/#{user.id}/sold_items", id: user.id
expect(response).to have_http_status(:success)
end
end
end
It seems your syntax is wrong.
change:
get "users/#{user.id}/sold_items"
To:
rails 4
get "users/:id/sold_items", id: user.id
rails 5
get "users/:id/sold_items", params: { id: user.id }