Why rails minitest testcases are failing - ruby-on-rails

My posts_controller_Test.rb file:
# test/controllers/posts_controller_test.rb
require 'test_helper'
class PostControllerTest < ActionController::TestCase
def setup
#post = Post.new
end
test 'should get index' do
get :index
assert_response :success
assert_not_nil assigns(:posts)
end
end
My post_controller File
class PostsController < ActionController::Base
before_action :authenticate_user!
def index
#post = current_user.posts.paginate(page: params[:page], per_page: 5)
respond_to do |format|
format.html
format.json { render json: #post }
end
end
def new
#post = Post.new
end
def create
#post = current_user.posts.build(post_param)
if #post.save
redirect_to action: 'index'
else
render 'new'
end
end
Why my test cases are failing? Is it because I have authenticate_user! condition? I also have .yml file and tried to test with it but after initializing with .yml data I am getting RuntimeError: #controller is nil: make sure you set it in your test's setup method.
yml file
one:
data 2
value: 3
user_id: 1
name: 'test'
.yml has everything what i have required in
params.require(:post).permit(:data, :value, :name) and obvious `user` for foreign key reference
Edit -1
After the suggestion of inheriting with ApplicationController
Got this new error:
NameError: uninitialized constant ApplicationController::Base
app/controllers/posts_controller.rb:3:in `<top (required)>'
app/controllers/posts_controller.rb:3:in `<top (required)>'
this is my line 3:
class PostsController < ApplicationController::Base
Edit-2
class PostsController < ApplicationController
got this:
NoMethodError: undefined method `authenticate!' for nil:NilClass

The error is because you've inherited your controller from the wrong class. Inherit from ApplicationController instead:
class PostsController < ApplicationController
...
end

Related

Rails Getting Error uninitialized constant ApplicationController (NameError)

I'm getting this error of ApplicationBaseController where it is throwing up a name error. Is there anything wrong in both of these codes because ruby is throwing errors even though i'm inheriting from the applicationbasecontroller in the application controller
class ShoppingController < ApplicationController
def index
#categories = Category.all()
end
def new
end
def showcollection
#products =Product.where(category_id: params[:id])
#productcount = Product.where(category_id: params[:id]).count
end
def create_product
#product = Product.new(product_params)
if (#product.save())
redirect_to shopping_index_path
else
render 'new'
end
end
private def product_params
params.require(:product).permit(:name,:price, :category_id, :image)
end
end
class ApplicationController < ActionController::Base
end
Also here is my directory structure
enter image description here

How to make the test name match the controller name?

I have this users_controller
class Api::V1::UsersController < ApplicationController
respond_to :json
def show
respond_with User.find(params[:id])
end
end
The file is in app/controllers/api/v1/
And my test is :
class Api::V1::UsersControllerTest < ActionController::TestCase
test '#show displays the specific user' do
#user = FactoryGirl.build(:user)
get :show, id: #user.id
assert_response :success
end
end
The file is in test/controllers/api/v1
When I run the test I get this error :
NameError: uninitialized constant Api
/Users/Ahmad/rails_apps/json_api/test/controllers/api/v1/users_controller_test.rb:1:in `<top (required)>'
What's going on?
Thanks
I think you miss
require 'test_helper'
at the top of your file. Give a try.

Rspec POST results in undefined method `key?' for :create:Symbol

When testing my controller I have a spec in Rspec using factorygirl for the data;
describe 'POST #create' do
context 'with valid attributes' do
it 'saves the new child in the database' do
expect{
post '/children', :create, person: attributes_for(:child)
}.to change(Person, :count).by(1)
end
I get an error
1) PeopleController POST #create with valid attributes saves the new child in the database
Failure/Error: post '/children', :create, person: attributes_for(:child)
NoMethodError:
undefined method key?' for :create:Symbol
# ./spec/controllers/people_controller_spec.rb:46:inblock (5 levels) in '
# ./spec/controllers/people_controller_spec.rb:45:in `block (4 levels) in '
My controller(this is everything so sorry about the irrelevant stuff)
class PeopleController < ApplicationController
before_action :set_person, only: [:show, :edit, :update, :destroy]
before_action :set_type
def full_name
[Person.christian_name, Person.surname].join ' '
end
def index
#people = type_class.all
end
def new
#person = type_class.new
end
def update
end
def show
end
def edit
end
def create
if #person_type == 'Child'
#person = Child.new(person_params)
else
#person = CareGiver.new(person_params)
end
if #person.save
redirect_to #person
else
render 'new'
end
end
def destroy
end
private
def person_params
if #person_type == 'Child'
params.require(:child).permit(:type, :christian_name, :surname, :dob, :gender)
else
params.require(:care_giver).permit(:type, :christian_name, :surname, :email,
:password, :password_confirmation)
end
end
def set_type
#person_type = type
end
def type
Person.types.include?(params[:type]) ? params[:type] : "Person"
end
def people_types
%w[Person Child Provider CareGiver]
end
def type_class
type.constantize if type.in? people_types
end
def set_person
#person = type_class.find(params[:id])
end
end
This is saving different types of person to a single table (sti).
It seems as though no params are passed to the controller. When I use debugger at this point I can create a Child object, but post doesn't pass it on. I added '/children' to get the correct route (although I read that rspec controller tests bypass the routes stack)
I have stared at it for hours and have that feeling in my stomach you get from not knowing why!
Thanks for any help
def set_type
#person_type = type
end
def type
Person.types.include?(params[:type]) ? params[:type] : "Person"
end
Found this code in my controller. the type method is not setting a value that #person_type could use. I got rid of method type, and change set_type to
def set_type
#person_type = params[:person][:type]
end
Not sure if this is safe? but now the test passes.
p.s. All the other tests broke!!

uninitialized constant API::V1::UserController

I know there are already a lot of questions about this on stackoverflow, but none of them works in my case.
In my routes.rb
Exer9::Application.routes.draw do
namespace :api, defaults: {format: 'json'} do
namespace :v1 do
resources :users
end
end
end
exer9/app/controllers/api/v1/users_controller.rb
module Api
module v1
class UsersController < ApplicationController
# GET /user
# GET /user.json
def index
#users = User.all
render json: #users
end
def new
end
def update
end
# GET /user/1
# GET /user/1.json
def show
#user = User.find(params[:id])
render json: #user
end
def create
#user = User.new(params[:user])
if #user.save
render json: #user
else
render json: #user.errors
end
end
def delete
end
def destroy
end
end
end
end
Update
This is my ApplicationController file
class ApplicationController < ActionController::API
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
# protect_from_forgery with: :exception
end
The error message that I get is:
superclass mismatch for class UsersController
Extracted source (around line #2):
1
2
3
4
5
6
class Api::V1::UsersController < ApplicationController
# GET /user
# GET /user.json
def index
Rails.root: /home/steven/Desktop/weekly-exercises/exer9
Application Trace | Framework Trace | Full Trace
app/controllers/api/v1/users_controller.rb:2:in `<top (required)>
'
Any help here is really appreciated!
Use shorter syntax, like:
class Api::V1::UsersController < ApplicationController
# your code goes here
end
Also, do you restart rails server after renaming classes and files?
Make sure your folder structure is correct:
users_controller.rb
should be found:
app/controllers/api/v1/users_controller.rb
You can use it like this
In routes.rb
namespace :api, defaults: {format: 'json'} do
scope module: :v1, constraints: ApiConstraints.new(version: 1 , default: true) do
resources :users
end
end
In controller
class Api::V1::UsersController < ApplicationController
# Your code here
end

Naming error in rails - creating API Controllers

I have my directory under app/controllers set up as such: api/v1/sessions_controller.rb I then have a BaseController: api/v1/base_controller.rb
I then set up each class to look as such:
module Api
module V1
class BaseController < ApplicationController
respond_to :json
before_action :default_json
protected
def default_json
request.format = :json if params[:format].nil?
end
def auth_only!
render :json: {}, status: 401 unless current_user
end
end
end
end
And then Sessions:
module Api
module V1
class SessionsController < BaseController
def create
user = User.authenticate(params[:user_name], params[:password])
if sign_in(user)
set_up_cookie(user)
render json: create_session_data, status: 201
else
invalid_user_crendentials
end
end
end
end
end
The tests are set up the same way, for example the sessions test is:
require 'spec_helper'
describe Api::V1::SessionsController do
before(:each) do
#user = FactoryGirl.create(:user)
end
context "Create a session" do
it "should NOT create a session" do
post :create
response.response_code.should == 401
end
end
end
The Error:
'<module:V1>': uninitialized constant Api::V1::BaseController (NameError)
Try formatting your naming slightly differently.
class Api::V1::BaseController < ApplicationController
# code
end
and
class Api::V1::SessionsController < BaseController
# might need to name this Api::V1::BaseController
end

Resources