Ruby on Rails controller test - ruby-on-rails

I have a problem with my testing. I have used scaffolds to create my app, but changed something in my controllers. My first controller looks as follow
class ChildrenController < ApplicationController
before_action :set_child, only: [:show, :edit, :update, :destroy]
require 'httparty'
# require 'open-uri'
include HTTParty
# include I18n
def child_admin
#children = Child.all
end
# GET /children
# GET /children.json
def index
#children = Child.all
end
# GET /children/1
# GET /children/1.json
def show
#child = Child.find(params[:id])
authorize! :read, #child
end
# GET /children/new
def new
#child = Child.new
end
# GET /children/1/edit
def edit
end
# POST /children
# POST /children.json
def create
#kigas = Kiga.all
#relations = Relation.all
#child = Child.new child_params
#child.user = current_user
url = "https://maps.googleapis.com/maps/api/geocode/json?address=#{I18n.transliterate(#child.city)}+#{I18n.transliterate(#child.streed)}+#{#child.add_number}&key=AIzaSyBWwoVj5WQMN9-Ij7IJWxQL1CzuigzBsYc"
latlongchild = HTTParty.get(url)
# puts latlongchild
# puts latlongchild["results"].first["geometry"]["location"]
childlat=latlongchild["results"].first["geometry"]["location"]["lat"]
childlng=latlongchild["results"].first["geometry"]["location"]["lng"]
# #child.save
respond_to do |format|
if #child.save
format.html { redirect_to #child, notice: 'Kind wurde erfolgreich registriert.' }
format.json { render :show, status: :created, location: #child }
else
format.html { render :new }
format.json { render json: #child.errors, status: :unprocessable_entity }
end
end
#kigas.each do |kiga|
url2 = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=#{I18n.transliterate(#child.city)}+#{I18n.transliterate(#child.streed)}+#{#child.add_number}&destinations=#{I18n.transliterate(kiga.city)}+#{I18n.transliterate(kiga.streed)}+#{kiga.add_number}&key=AIzaSyDjh9hMXm_lnIyaj_HLQpGvDcDasLjyhxk"
response = HTTParty.get(url2)
mesponse=response["rows"].first["elements"].first["distance"]["value"]
url3 = "https://maps.googleapis.com/maps/api/geocode/json?address=#{I18n.transliterate(kiga.city)}+#{I18n.transliterate(kiga.streed)}+#{kiga.add_number}&key=AIzaSyBWwoVj5WQMN9-Ij7IJWxQL1CzuigzBsYc"
response2 = HTTParty.get(url3)
kigalat=response2["results"].first["geometry"]["location"]["lat"]
kigalng=response2["results"].first["geometry"]["location"]["lng"]
# puts mesponse
# puts mysponse
# puts #child.id
# puts kiga.id
#relation = Relation.new relation_params
#relation.child_id = #child.id
#relation.kiga_id = kiga.id
#relation.distance = mesponse
#relation.kigalat = kigalat
#relation.kigalong = kigalng
#relation.childlat = childlat
#relation.childlong = childlng
#relation.user_id = #child.user_id
#relation.save
end
end
# PATCH/PUT /children/1
# PATCH/PUT /children/1.json
def update
respond_to do |format|
if #child.update(child_params)
format.html { redirect_to #child, notice: 'Kind wurde erfolgreich angepasst.' }
format.json { render :show, status: :ok, location: #child }
else
format.html { render :edit }
format.json { render json: #child.errors, status: :unprocessable_entity }
end
end
end
# DELETE /children/1
# DELETE /children/1.json
def destroy
#child.destroy
respond_to do |format|
format.html { redirect_to children_url, notice: 'Kind wurde erfolgreich ausgetragen.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_child
#child = Child.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def child_params
params.require(:child).permit(:name, :city, :postalcode, :streed, :add_number, :disability, :halal, :koscha, :vegetarian, :vegan, :allday, :gender)
end
def set_relation
#relation = Relation.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def relation_params
# params.require(:relation).permit(:kiga_id, :child_id, :assignment, :preference, :distance)
end
end
and my controller test as follows:
require 'test_helper'
class ChildrenControllerTest < ActionDispatch::IntegrationTest
setup do
#child = children(:one)
end
test "should get index" do
get children_url
assert_response :success
end
test "should get new" do
get new_child_url
assert_response :success
end
test "should create child" do
assert_difference('Child.count') do
post children_url, params: { child: { add_number: #child.add_number, allday: #child.allday, city: #child.city, disability: #child.disability, gender: #child.gender, halal: #child.halal, koscha: #child.koscha, name: #child.name, postalcode: #child.postalcode, streed: #child.streed, vegan: #child.vegan, vegetarian: #child.vegetarian } }
end
assert_redirected_to child_url(Child.last)
end
test "should show child" do
get child_url(#child)
assert_response :success
end
test "should get edit" do
get edit_child_url(#child)
assert_response :success
end
test "should update child" do
patch child_url(#child), params: { child: { add_number: #child.add_number, allday: #child.allday, city: #child.city, disability: #child.disability, gender: #child.gender, halal: #child.halal, koscha: #child.koscha, name: #child.name, postalcode: #child.postalcode, streed: #child.streed, vegan: #child.vegan, vegetarian: #child.vegetarian } }
assert_redirected_to child_url(#child)
end
test "should destroy child" do
assert_difference('Child.count', -1) do
delete child_url(#child)
end
assert_redirected_to children_url
end
end
and I've also defined some abilities:
class Ability
include CanCan::Ability
def initialize(user)
if user.admin?
can :manage, :all
can :view, Child
can :view, Kiga
can :read, Kiga
can :read, Child
can :read, User
elsif user.role == 'Eltern'
can [:update, :destroy], Child do |child|
child.user_id == user.id
end
can :view, Child do |child|
child.user_id == user.id
end
can :read, Child do |child|
child.user_id == user.id
end
can :create, Child
can :read, Kiga
can :results_child, Child
can [:read, :view], Relation do |relation|
relation.user_id == user.id
end
else
end
end
end
I'm usingtest_helper and cancanfor the abilities. I thought my change in the abilities destroyed my testing, because my index, show, create and update test produces errors with the following massage
ActionView::Template::Error: undefined method 'admin?' for nil:NilClass
Can someone help me and can tell me, how I have to rearrange my controller and tests? Or is there another big mistake?
Thank you very much!

The user.admin? call is what's causing the error.
The ability.rb that gets generated by cancancan includes a commented out line as part of the example:
# user ||= User.new # guest user (not logged in)
This is because when you don't have a signed in user nil gets passed in to create the Ability instance.
With user ||= User.new it means that you have an actual, although not saved, user instance to interact with. Putting that line as the first in your initialize method for Ability is probably easier than making all your user checks something like if user && user.admin?.

Related

Rails - How to pass controller tests when I use before_action

I need to run some tests and I have come at a stand still here.
I am using before_action in my Appointments controller
Here is the controller
class AppointmentsController < ApplicationController
before_action :set_appointment, only: %i[ show edit update destroy ]
#before we run anything if the user is not signed in show index and show functions
before_action :authenticate_user!, except: [:index,:show]
#only the correct user can edit,update and destroy
before_action :correct_user, only: [:edit, :update , :destroy]
# GET /appointments or /appointments.json
def index
#appointments = Appointment.all.decorate
end
# GET /appointments/1 or /appointments/1.json
def show
end
# GET /appointments/new
def new
##appointment = Appointment.new
#appointment = current_user.appointments.build
end
# GET /appointments/1/edit
def edit
end
#function to allow for search functionality
def search
#appointments = Appointment.where("date LIKE?", "%"+params[:q]+"%")
end
# POST /appointments or /appointments.json
def create
##appointment = Appointment.new(appointment_params)
#appointment = current_user.appointments.build(appointment_params)
#here underneath I am using my custom gem to filter bad words within the notes field when creating an appointment
#appointment.notes = Badwordgem::Base.sanitize(#appointment.notes)
respond_to do |format|
if #appointment.save
format.html { redirect_to appointment_url(#appointment), notice: "Appointment was successfully created." }
format.json { render :show, status: :created, location: #appointment }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /appointments/1 or /appointments/1.json
def update
respond_to do |format|
if #appointment.update(appointment_params)
format.html { redirect_to appointment_url(#appointment), notice: "Appointment was successfully updated." }
format.json { render :show, status: :ok, location: #appointment }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /appointments/1 or /appointments/1.json
def destroy
#appointment.destroy
respond_to do |format|
format.html { redirect_to appointments_url, notice: "Appointment was successfully destroyed." }
format.json { head :no_content }
end
end
#function here that restricts editing so the current logged in user can edit only their records
def correct_user
#appointment = current_user.appointments.find_by(id: params[:id])
redirect_to appointments_path, notice:"NOT ALLOWED TO EDIT THIS" if #appointment.nil?
end
private
# Use callbacks to share common setup or constraints between actions.
def set_appointment
#appointment = Appointment.find(params[:id])
end
# Only allow a list of trusted parameters through.
def appointment_params
params.require(:appointment).permit(:barber, :customer, :notes, :date,:user_id)
end
end
and here is my test controller
require "test_helper"
class AppointmentsControllerTest < ActionDispatch::IntegrationTest
Devise::Test::IntegrationHelpers
setup do
#appointment = appointments(:one)
end
test "should get index" do
get appointments_url
assert_response :success
end
test "should get new" do
get new_appointment_url
assert_response :success
end
test "should create appointment" do
assert_difference('Appointment.count') do
post appointments_url, params: { appointment: { barber: #appointment.barber, customer: #appointment.customer, date: #appointment.date, notes: #appointment.notes } }
end
assert_redirected_to appointment_url(Appointment.last)
end
test "should show appointment" do
get appointment_url(#appointment)
assert_response :success
end
test "should get edit" do
get edit_appointment_url(#appointment)
assert_response :success
end
test "should update appointment" do
patch appointment_url(#appointment), params: { appointment: { barber: #appointment.barber, customer: #appointment.customer, date: #appointment.date, notes: #appointment.notes } }
assert_redirected_to appointment_url(#appointment)
end
test "should destroy appointment" do
assert_difference('Appointment.count', -1) do
delete appointment_url(#appointment)
end
assert_redirected_to appointments_url
end
end
If I comment out the "before actions" in my controller , of course all the tests pass but with them 15 tests fail.
How do I make the tests pass with the before_action ?
For :authenticate_user just use the helper log_in in te test, after create a user, like this:
class AppointmentsControllerTest < ActionDispatch::IntegrationTest
let(:user) { User.new(user_params) }
......
and put
sign_ig user
inside each 'it methods you want'
For :set_appointment or :correct_user just passing right id params inside the path's call

NoMethodError:undefined method `employee' for nil:NilClass for RSPEC test Rails

I want to run the rspec of Tickets controllers, I Have used scaffold and I have made some changes according to my project.
but I am getting some errors. I also have a login (using Devise).
How do I go ahead?
This is the controller-
class TicketsController < ApplicationController
before_action :set_ticket, only: %i[ show edit update destroy assign]
before_action :set_assign_ticket, only: %i[assignid]
# shows the landing page of employee
def landing
#tickets = current_user.employee.tickets.order('tstatus_id, id desc')
end
# Service engineer index showing the tickets which are assinged to him
def slanding
#tickets = Ticket.where(service_id: current_user.employee.service_id).order('tstatus_id, id desc')
end
# Showing tickets list based on the user type
def index
#tickets = if current_user.employee.designation.role == "ADMIN"
Ticket.all.order('tstatus_id ,id desc ')
else
Ticket.where(employee: current_user.employee)
end
end
def show
#tickets = Ticket.all
end
def new
#ticket = Ticket.new
end
#creating a new ticket
def create
#ticket = Ticket.new(ticket_params)
#ticket.employee = current_user.employee
respond_to do |format|
if #ticket.save
format.html { redirect_to landing_path}
else
format.html { render :new, status: :unprocessable_entity }
end
end
end
# updating a ticket
def update
respond_to do |format|
if #ticket.update(ticket_params)
if current_user.employee.designation.role == "ADMIN"
format.html { redirect_to tickets_url }
else
format.html { redirect_to slanding_path }
end
else
format.html { render :edit, status: :unprocessable_entity }
end
end
end
private
def set_ticket
#ticket = Ticket.where(id: params[:id]).first
end
def ticket_params
params.require(:ticket).permit(:kind, :description, :dev_id, :service_id,:tstatus_id)
end
def set_assign_ticket
#ticket = Ticket.find(params[:id])
end
end
This is the model -
class Ticket < ApplicationRecord
belongs_to :service, optional: true
belongs_to :employee
belongs_to :tstatus
before_validation(on: :create) do
self.service_id = 4 # this will assign the service engineer to NONE
self.tstatus_id = 1 # this will assign the status to logged
end
validates :description, presence: true
end
My test cases are:
require 'rails_helper'
describe TicketsController, type: :controller do
# describe 'GET show' do
it 'gets show based on ID' do
#ticket = Ticket.new(id: 1,kind: "Example Ticket", description: "Ticket#example.com", service_id: 1, employee_id: 1,tstatus_id:1)
get :show, params: { id: #ticket.id }
expect(response.status).to eq(200)
end
# describe 'GET edit' do
it 'has 200 status code' do
get :new
expect(response.status).to eq(200)
end
describe 'POST create' do
it 'has 200 status code' do
mock = double('Employee')
expect(mock).to receive(:employee_id)
post :create, params: {
ticket: {
id: 1,kind: "Example Ticket", description: "Ticket#example.com", service_id: 1, employee_id: 1,tstatus_id:1
}
}
expect(response.status).to eq 302
end
end
end
I am a newbie to rails,
Can someone tell me how to write test cases for the controller above?

Test controller failed: NoMethodError: undefined method `env' for nil:NilClass

I have a problem with unit testing in ruby on rails (rails v. 5.001). The user needs to login in a test unit, but how can I implement this? Here is the code:
appointments_controller_test.rb
require 'test_helper'
class AppointmentsControllerTest < ActionDispatch::IntegrationTest
include Devise::TestHelpers
setup do
#heikoAppointment = appointments(:appointment_heiko)
#heiko = users(:heiko)
heiko = users(:heiko)
end
test "should get index" do
get appointments_url
assert_response :success
end
test "should get new" do
sign_in #heiko
get new_appointment_url
assert_response :success
end
......
appointments_controller.rb
class AppointmentsController < ApplicationController
load_and_authorize_resource
layout 'appointment', only: [:shopper_show, :senior_show]
def index
#shopping_lists = ShoppingList.where(user_id: current_user.id)
#users = User.senior.where.not(id: current_user.id).order(:firstname)
##appointments = Appointment.where(user_id: current_user.id)
##invitations = Invitation.where(user_id: current_user.id)
#todo: merge #invitations.appointmen into #appointments
end
# GET /shopping_processes/1
# GET /shopping_processes/1.json
def show
#appointment = Appointment.find(params[:id])
#shopping_lists = get_both_lists
#users = get_both_users
end
# POST /shopping_processes
# POST /shopping_processes.json
def create
#appointment.status = nil
#appointment.processed = nil
#appointment.user_id = current_user.id
sl_created = create_shopping_list?
respond_to do |format|
if #appointment.save
format.html { redirect_to #appointment, notice: t(:appointment_created) }
format.json { render :show, status: :created, location: #appointment }
else
if sl_created
ShoppingList.find(#appointment.shopping_list_id).destroy
end
format.html { render :new }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /shopping_processes/1
# PATCH/PUT /shopping_processes/1.json
def update
respond_to do |format|
if #appointment.update(appointment_params)
format.html { redirect_to #appointment, notice: t(:appointment_updated) }
format.json { render :show, status: :ok, location: #appointment }
else
format.html { render :edit }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /shopping_processes/1
# DELETE /shopping_processes/1.json
def destroy
#appointment.destroy
respond_to do |format|
format.html { redirect_to appointments_url, notice: t(:appointment_deleted) }
format.json { head :no_content }
end
end
def shopper_index
end
def ready_index
appointments_hash = {}
customers = User.where.not(current_appointment: nil).where(role: :senior)
customers.each {|user| appointments_hash[user.current_appointment.id] = user.current_appointment}
shoppers = User.where.not(current_appointment: nil).where(role: :shopper)
shoppers.each {|user| appointments_hash.delete(user.current_appointment.id)}
#appointments = []
appointments_hash.each { |appointment_id, appointment| #appointments.push(appointment)}
end
def shopper_show
#appointment = Appointment.find(params[:id])
#shopping_lists = get_both_lists
both_users = get_both_users
#users = {}
first = true
both_users.each do |user|
#users[user.id] = {color: (first ? 'blue' : 'yellow'), name: user.firstname + ' ' + user.lastname}
first = false
end
end
def senior_show
#appointment = Appointment.find(params[:id])
if #appointment.user == current_user
#shopping_list = #appointment.shopping_list
else
#shopping_list = #appointment.invitation.shopping_list
end
#D.S.:Diese zuweisung funktioniert nicht richtig. Sie wurde vor den DB änderung erstellt und muss angepasst werden
#D.S.:ShoppingItem.joins(:list_item) und ListItem.where(shopping_list_id: #shopping_list.id]) ergeben ein korrektes Resultat
#D.S.:Aber zusammengenommen ist die query leer
##shopping_items = ShoppingItem.joins(:list_item).where(list_item: [shopping_list_id: #shopping_list.id])
end
private def get_both_lists
shopping_lists = [ #appointment.shopping_list]
if #appointment.invitation && #appointment.invitation.shopping_list
shopping_lists << #appointment.invitation.shopping_list
end
shopping_lists
end
private def get_both_users
users = [ #appointment.user]
if #appointment.invitation
users.push(#appointment.invitation.user)
end
users
end
private
# Use callbacks to share common setup or constraints between actions.
def set_appointment
#appointment = Appointment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def appointment_params
params.require(:appointment).permit(:shopper_id, :status, :appointed, :processed, :shopping_list_id, invitation_attributes: [:user_id, :message ])
end
def create_shopping_list?
if #appointment.shopping_list_id.blank?
name = "Liste für den " + #appointment.appointed.strftime("%d.%m.%Y").to_s
invitee_id = "" + (#appointment.invitation.user_id.to_s) if #appointment.invitation
name = name + ( " mit " + User.find(invitee_id).firstname) unless invitee_id.blank?
sl = current_user.shopping_lists.create(:name => name)
#appointment.shopping_list_id = sl.id
true
else
false
end
end
end
And here is the Error I get when I run the test:
Error:
AppointmentsControllerTest#test_should_get_new:
NoMethodError: undefined method `env' for nil:NilClass
Does somebody know the solution? I would be very thankful
UPDATE: include Devise::TestHelpers is deprecated. Now I use include Devise::Test::IntegrationHelpers. Now my appointments_controller_test.rb looks like this:
require 'test_helper'
class AppointmentsControllerTest < ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers
def sign_in(user)
post user_session_path \
"heiko#me.com" => user.email,
"hhdk#s0" => user.password
end
setup do
#heikoAppointment = appointments(:appointment_heiko)
#heiko = users(:user_heiko)
sign_in(#heiko)
end
test "should get index" do
get appointments_url
assert_response :success
end
test "should get new" do
sign_in(#heiko)
get new_appointment_url
assert_response :success
end
However I get another error:
AppointmentsControllerTest#test_should_get_new [C:/Users/Clemens/meindorfladen/Server/test/controllers/appointments_controller_test.rb:33]:
Expected response to be a <2XX: success>, but was a <302: Found> redirect to <http://www.example.com/users/sign_in>
Does somebody knows why there is this redirect to http://www.example.com/users/sign_in? I thought now the user is signed in
You should include Devise::Test::IntegrationHelpers not Devise::TestHelpers as per the readme.

Rails Controllers tests are not working

I am trying to do my first tests on rails but I am having troubles with it.
I am trying just to test one controller to understand how it works but it doesn't work.
I added the Devise helper to avoid problems with it but I still getting many errors.
I really appreciate so much any kind of help.
Here is the code of the Test Controller:
reportes_controller_test.rb
require 'test_helper'
class ReportesControllerTest < ActionController::TestCase
include Devise::TestHelpers
setup do
#reporte = reportes(:one)
end
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:reportes)
end
test "should get new" do
get :new
assert_response :success
end
test "should create report" do
assert_difference('Reporte.count') do
post :create, reporte: { asignacion_actividad_id: #reporte.asignacion_actividad_id, descripcion: #reporte.descripcion}
end
assert_redirected_to reporte_path(assigns(:reporte))
end
test "should show report" do
get :show, id: #reporte
assert_response :success
end
test "should get edit" do
get :edit, id: #reporte
assert_response :success
end
test "should update report" do
patch :update, id: #reporte, reporte: { asignacion_actividad_id: #reporte.asignacion_actividad_id, descripcion: #reporte.descripcion}
assert_redirected_to reporte_path(assigns(:reporte))
end
test "should destroy report" do
assert_difference('Reporte.count', -1) do
delete :destroy, id: #reporte
end
assert_redirected_to reportes_path
end
end
Here is the code of the Controller:
reportes_controller.rb
class ReportesController < ApplicationController
before_action :set_reporte, only: [:show, :edit, :update, :destroy]
# asd
#
# GET /reportes
# GET /reportes.json
def index
authorize! :index, Reporte
#asignacion_actividades = AsignacionActividad.find_by(actividad_id: params[:actividad_id])
#actividad = #asignacion_actividades.actividad
#proyecto = #actividad.proyecto
#reportes_mios = []
#asignacion_actividades.to_a.each do |asignacion|
if asignacion.usuario == current_usuario && !asignacion.reportes.nil?
#reportes_mios = #reportes_mios + asignacion.reportes
end
end
#reportes_todos = #actividad.reportes
#reportes_todos = [] if #reportes_todos.nil?
#reportes_mios = [] if #reportes_mios.nil?
#reportes_todos = #reportes_todos.uniq
#reportes_mios = #reportes_mios.uniq
end
# GET /reportes/1
# GET /reportes/1.json
def show
authorize! :show, Reporte
end
# GET /reportes/new
def new
authorize! :new, Reporte
#actividad = Actividad.find(params[:actividad_id])
#proyecto = #actividad.proyecto
#asignacion_actividad = #actividad.asignacion_actividades.where('vigente =? and usuario_id =?', 'true' , current_usuario.id).uniq.last
#asignacion_actividad_id = #asignacion_actividad.id
#reporte = Reporte.new
end
# GET /reportes/1/edit
def edit
authorize! :edit, Reporte
end
# POST /reportes
# POST /reportes.json
def create
authorize! :create, Reporte
#reporte = Reporte.new(reporte_params)
respond_to do |format|
if #reporte.save
format.html { redirect_to :action => 'index', :actividad_id => #reporte.asignacion_actividad.actividad.id
flash[:notice] = 'Reporte was successfully created.' }
format.json { render :show, status: :created, location: #reporte }
else
format.html { render :new }
format.json { render json: #reporte.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /reportes/1
# PATCH/PUT /reportes/1.json
def update
authorize! :update, Reporte
respond_to do |format|
if #reporte.update(reporte_params)
format.html { redirect_to #reporte, notice: 'Reporte was successfully updated.' }
format.json { render :show, status: :ok, location: #reporte }
else
format.html { render :edit }
format.json { render json: #reporte.errors, status: :unprocessable_entity }
end
end
end
# DELETE /reportes/1
# DELETE /reportes/1.json
def destroy
authorize! :destroy, Reporte
#reporte.destroy
respond_to do |format|
format.html { redirect_to reportes_url, notice: 'Reporte was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_reporte
#reporte = Reporte.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def reporte_params
params.require(:reporte).permit(:descripcion, :asignacion_actividad_id)
end
end
And here is the error that I get when i try to execute it:
rake test TEST=test/controllers/reportes_controller_test.rb
Run options: --seed 7969
# Running:
FFFFFFE
Finished in 0.540113s, 12.9603 runs/s, 11.1088 assertions/s.
1) Failure:
ReportesControllerTest#test_should_create_report [/home/blackswan/proyectoFinal/SEVU/test/controllers/reportes_controller_test.rb:21]:
"Reporte.count" didn't change by 1.
Expected: 3
Actual: 2
2) Failure:
ReportesControllerTest#test_should_destroy_report [/home/blackswan/proyectoFinal/SEVU/test/controllers/reportes_controller_test.rb:44]:
"Reporte.count" didn't change by -1.
Expected: 1
Actual: 2
3) Failure:
ReportesControllerTest#test_should_get_edit [/home/blackswan/proyectoFinal/SEVU/test/controllers/reportes_controller_test.rb:35]:
Expected response to be a <success>, but was <302>
4) Failure:
ReportesControllerTest#test_should_get_index [/home/blackswan/proyectoFinal/SEVU/test/controllers/reportes_controller_test.rb:11]:
Expected response to be a <success>, but was <302>
5) Failure:
ReportesControllerTest#test_should_get_new [/home/blackswan/proyectoFinal/SEVU/test/controllers/reportes_controller_test.rb:17]:
Expected response to be a <success>, but was <302>
6) Failure:
ReportesControllerTest#test_should_show_report [/home/blackswan/proyectoFinal/SEVU/test/controllers/reportes_controller_test.rb:30]:
Expected response to be a <success>, but was <302>
7) Error:
ReportesControllerTest#test_should_update_report:
ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"reportes", :id=>nil} missing required keys: [:id]
test/controllers/reportes_controller_test.rb:40:in `block in <class:ReportesControllerTest>'
7 runs, 6 assertions, 6 failures, 1 errors, 0 skips
What can i do? If i solve this error I will be able to test all the controllers.
I will appreaciate any answer. Thank you for your time.
I think it about authorization, is your controller works well?
If you don't mind, you can take a look on RedMine, it has many test case to refer.

undefined method for nil:NilClass in RSpec

I'm using RSpec, and I get this error when running tests:
Failure/Error: before { get edit_job_path(job) }
NoMethodError:
undefined method `jobs' for nil:NilClass
# ./app/controllers/jobs_controller.rb:63:in `correct_user'
# ./spec/requests/authentication_pages_spec.rb:35:in `block (6 levels) in <top (required)>'
The actual behavior of the page (when doing rails server) seems fine. Why is the test not working? I'm still a beginner to Ruby/Rails, so any help would be appreciated.
Some code for help:
authentication_pages_spec.rb
require 'spec_helper'
describe "Authentication" do
subject { page }
describe "signin" do
[...]
describe "authorization" do
describe "for non-signed in users" do
describe "when attempting to visit a protected page" do
let(:user) { FactoryGirl.create(:user) }
let(:job) { FactoryGirl.create(:job, user: user) }
before { get edit_job_path(job) }
it { should_not have_content('Editing job') }
describe "after signing in" do
[...]
end
[...]
end
end
[...]
end
end
end
jobs_controller.rb
class JobsController < ApplicationController
before_action :signed_in_user, only: [:new, :create, :update]
before_action :correct_user, only: [:edit, :update, :destroy]
before_action :set_job, only: [:show, :edit, :update, :destroy]
def index
#jobs = Job.all
end
def show
end
def new
#job = Job.new
end
def edit
end
def create
#job = current_user.jobs.build(job_params)
respond_to do |format|
if #job.save
format.html { redirect_to #job, notice: 'Job was successfully created.' }
format.json { render action: 'show', status: :created, location: #job }
else
format.html { render action: 'new' }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #job.update(job_params)
format.html { redirect_to #job, notice: 'Job was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
def destroy
#job.destroy
respond_to do |format|
format.html { redirect_to jobs_url }
format.json { head :no_content }
end
end
private
def set_job
#job = Job.find(params[:id])
end
def job_params
params.require(:job).permit(:title, :org, :internship, :postdate, :filldate, :location, :link, :description)
end
def correct_user
#job = current_user.jobs.find_by(id: params[:id])
redirect_to root_url, notice: 'You can only edit your own jobs.' if #job.nil?
end
end
factories.rb
FactoryGirl.define do
factory :user do
sequence(:name) { |n| "Johnny #{n}" }
sequence(:email) { |n| "johnny_#{n}#example.com" }
password "sampleton"
password_confirmation "sampleton"
end
factory :job do
sequence(:title) { |n| "Example Title #{n}" }
user
end
end
sessions_helper.rb
module SessionsHelper
[...]
def current_user=(user)
#current_user = user
end
def current_user
remember_token = User.encrypt(cookies[:remember_token])
#current_user ||= User.find_by(remember_token: remember_token)
end
[...]
def signed_in?
!current_user.nil?
end
def signed_in_user
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in."
end
end
[...]
def store_location
session[:return_to] = request.url if request.get?
end
[...]
end
Your test seems to be working fine in that they've uncovered a bug. Your action expects that current_user be set, and it isn't, so you're getting an error.
You need a before_filter which redirects you when you hit a page that requires authorization.

Resources