ArgumentError too few arguments when trying to test the controller - ruby-on-rails

I'm trying to learn how to do tests in Rails. I have a foods_controller and in the test folder, my food.yml is filled with all of the parameters that should be present when creating a new food object and in foods_controller_test.rb, the parameters in "should create food" are matching the ones in food.yml. When running a test I get this error:
ArgumentError: too few arguments
app/controllers/application_controller.rb:45:in `format'
app/controllers/application_controller.rb:45:in `authorize'
test/controllers/foods_controller_test.rb:21:in `block (2 levels) in <class:FoodsControllerTest>'
test/controllers/foods_controller_test.rb:20:in `block in <class:FoodsControllerTest>
Can anyone exaplain me what is wrong here?
food.yml
one:
name: "Whatever"
portion: "100g"
calories: 1
fat: 1.5
carb: 1.5
protein: 1.5
fiber: 1.5
sugar: 1.5
category: "Grains"
two:
name: "MyString"
portion: "MyString"
calories: 1
fat: 1.5
carb: 1.5
protein: 1.5
fiber: 1.5
sugar: 1.5
category: "MyString"
foods_controller_test.rb
require 'test_helper'
class FoodsControllerTest < ActionController::TestCase
setup do
#food = foods(:one)
end
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:foods)
end
test "should get new" do
get :new
assert_response :success
end
test "should create food" do
assert_difference('Food.count') do
post :create, food: { calories: #food.calories, carb: #food.carb, category: #food.category, fat: #food.fat, fiber: #food.fiber, name: #food.name, portion: #food.portion, protein: #food.protein, sugar: #food.sugar }
end
assert_redirected_to food_path(assigns(:food))
end
test "should show food" do
get :show, id: #food
assert_response :success
end
test "should get edit" do
get :edit, id: #food
assert_response :success
end
test "should update food" do
patch :update, id: #food, food: { calories: #food.calories, carb: #food.carb, category: #food.category, fat: #food.fat, fiber: #food.fiber, name: #food.name, portion: #food.portion, protein: #food.protein, sugar: #food.sugar }
assert_redirected_to food_path(assigns(:food))
end
test "should destroy food" do
assert_difference('Food.count', -1) do
delete :destroy, id: #food
end
assert_redirected_to foods_path
end
end
foods_controller.rb
class FoodsController < ApplicationController
before_action :set_food, only: [:show, :edit, :update, :destroy]
before_filter :authorize, only: [:create, :delete]
# GET /foods
# GET /foods.json
def index
#foods = Food.order(:name)
# #foods = #foods.sort_by &:name
# #users.sort! { |a,b| a.name.downcase <=> b.name.downcase }
#food_categories = Food::CATEGORIES.keys.sort
# #current_category ||= params(:category)
day_selected = params[:day_selected]
meal_selected = params[:meal_selected]
end
# GET /foods/1
# GET /foods/1.json
def show
end
# GET /foods/new
def new
#food = Food.new
end
# GET /foods/1/edit
def edit
end
# POST /foods
# POST /foods.json
def create
#food = Food.new(food_params)
respond_to do |format|
if #food.save
format.html { redirect_to foods_url, notice: 'Food was successfully created.' }
format.json { render :show, status: :created, location: #food }
else
format.html { render :new }
format.json { render json: #food.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /foods/1
# PATCH/PUT /foods/1.json
def update
respond_to do |format|
if #food.update(food_params)
format.html { redirect_to foods_url, notice: 'Food was successfully updated.' }
format.json { render :show, status: :ok, location: #food }
else
format.html { render :edit }
format.json { render json: #food.errors, status: :unprocessable_entity }
end
end
end
# DELETE /foods/1
# DELETE /foods/1.json
def destroy
#current_user.entries.where(food_id: "#{#food.id}").delete_all
#food.destroy
respond_to do |format|
format.html { redirect_to foods_url, notice: 'Food was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_food
#food = Food.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def food_params
params.require(:food).permit(:name, :portion, :calories, :fat, :carb, :protein,
:fiber, :sugar, :category, :added_by, :cholesterol,
:potassium, :sodium, :trans_fat, :monounsaturated_fat,
:polyunsaturated_fat, :saturated_fat)
end
end
food.rb
class Food < ActiveRecord::Base
belongs_to :user
CATEGORIES = { "Dairy & Eggs" => "Dairy",
"Meat & Fish" => "Animal",
"Fruits & Vegetables" => "Plant",
"Nuts, beans & legumes" => "Nuts",
"Grains" => "Grains",
"Drinks" => "Beverages",
"Sweets & Candy" => "Sweets",
"Oils & Fats" => "Oils",
"Other" => "Other" }
validates :name, presence: true
validates :portion, presence: true
validates :calories, presence: true
validates :fat, presence: true
validates :carb, presence: true
validates :protein, presence: true
validates :category, presence: true
end

Try specifying the format in the test example, in your case json or html.
post :create, format: json, food: { ... }

Related

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?

Tests failed after add 'belongs_to' to model in Rails application

Tests failed after add belongs_to in Rails
I have 2 models in Rails application:
class Micropost < ApplicationRecord
belongs_to :user # Test failed after add this string
validates :content, length: { maximum: 140 }, presence: true
end
class User < ApplicationRecord
has_many :microposts
validates :name, presence: true
validates :email, presence: true
end
I added string "belongs_to :user" to model "Micropost". After that I ran tests, and they failed:
rails test
1) Failure:
MicropostsControllerTest#test_should_create_micropost [/home/kiselev/project/toy_app/test/controllers/microposts_controller_test.rb:19]:
"Micropost.count" didn't change by 1.
Expected: 3
Actual: 2
2) Failure:
MicropostsControllerTest#test_should_update_micropost [/home/kiselev/project/toy_app/test/controllers/microposts_controller_test.rb:38]:
Expected response to be a <3XX: redirect>, but was a <200: OK>
I have these 2 tests:
test "should create micropost" do
assert_difference('Micropost.count') do
post microposts_url, params: { micropost: { content: #micropost.content, user_id: #micropost.user_id } }
end
assert_redirected_to micropost_url(Micropost.last)
end
test "should update micropost" do
patch micropost_url(#micropost), params: { micropost: { content: #micropost.content, user_id: #micropost.user_id } }
assert_redirected_to micropost_url(#micropost)
end
I have a controller "MicropostsController":
class MicropostsController < ApplicationController
before_action :set_micropost, only: [:show, :edit, :update, :destroy]
# POST /microposts
# POST /microposts.json
def create
#micropost = Micropost.new(micropost_params)
respond_to do |format|
if #micropost.save
format.html { redirect_to #micropost, notice: 'Micropost was successfully created.' }
format.json { render :show, status: :created, location: #micropost }
else
format.html { render :new }
format.json { render json: #micropost.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /microposts/1
# PATCH/PUT /microposts/1.json
def update
respond_to do |format|
if #micropost.update(micropost_params)
format.html { redirect_to #micropost, notice: 'Micropost was successfully updated.' }
format.json { render :show, status: :ok, location: #micropost }
else
format.html { render :edit }
format.json { render json: #micropost.errors, status: :unprocessable_entity }
end
end
end
Setup micropost:
class MicropostsControllerTest < ActionDispatch::IntegrationTest
setup do
#micropost = microposts(:one)
end
Params in Micropost controller:
def micropost_params
params.require(:micropost).permit(:content, :user_id)
end
Fixtures Micropost:
one:
content: MyText
user_id: 1
two:
content: MyText
user_id: 1
How can I improve these tests to pass?
belongs_to method adds among others also a presence validation for the user. Somewhere in the rails code it adds something like:
validates_presence_of :user
And it checks whether the user exists. In your fixtures you have set user_id: 1. But in your tests there is no user with 1 as an ID. To fix it you have to set correct user IDs for your microposts fixtures.
You can do it in the following way. You don't have to define user_id, you can define association in the fixtures:
one:
content: MyText
user: one
two:
content: MyText
user: one
Define a user key instead of user_id and as a value use the name of the fixture from the user fixtures - in tests it would be called users(:one) if you would want to access this fixture.
Note: You can also remove the presence validation by adding required: false to your belongs_to definition but I would not recommend it.

Controller test: "ShoppingList.count" didn't change by 1. Expected: 3 Actual: 2

I test the controlller "shopping_list". However when I start the test I get this error:
Failure:
ShoppingListsControllerTest#test_should_create_shopping_list [C:/Users/Clemens/meindorfladen/Server/test/controllers/shopping_lists_controller_test.rb:30]:
"ShoppingList.count" didn't change by 1.
Expected: 3
Actual: 2
So one parameter is missing, but how can this be? Does somebody know the answer? Here is the code:
shopping_lists.yml
shopping_list_drogerie:
user: user_heiko
name: Drogerie
created_at: <%= Time.now %>
updated_at: <%= Time.now %>
shopping_list_lebensmittel:
user: user_schmitt
name: Lebensmittel
created_at: <%= Time.now %>
updated_at: <%= Time.now %>
db/schema
create_table "shopping_lists", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
t.index ["user_id"], name: "index_shopping_lists_on_user_id", using: :btree
end
models/shopping_list.rb
class ShoppingList < ApplicationRecord
# db associations
belongs_to :user
# if a shopping list is deleted, also delete information about all items on the list
has_many :list_items, :dependent => :destroy
# if a shopping list is deleted, also delete information about who it was shared with
has_many :shared_lists , :dependent => :destroy
has_many :shared_with_users,through: :shared_lists, :source => :user
has_many :invitation
has_one :appointment
# validations
validates :user, :presence => true
validates :name, presence: true, allow_blank: false, uniqueness: {scope: :user_id}
end
controllers/shopping_lists_controller.rb
class ShoppingListsController < ApplicationController
load_and_authorize_resource
# GET /shopping_lists/1
# GET /shopping_lists/1.json
def show
end
# POST /shopping_lists
# POST /shopping_lists.json
def create
respond_to do |format|
if #shopping_list.save
format.html { redirect_to shopping_list_list_items_path(#shopping_list), alert: 'Shopping list was successfully created.' }
format.json { render :show, status: :created, location: #shopping_list }
else
format.html { render :new }
format.json { render json: #shopping_list.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /shopping_lists/1
# PATCH/PUT /shopping_lists/1.json
def update
respond_to do |format|
if #shopping_list.update(shopping_list_params)
format.html { redirect_to #shopping_list, notice: 'Shopping list was successfully updated.' }
format.json { render :show, status: :ok, location: #shopping_list }
else
format.html { render :edit }
format.json { render json: #shopping_list.errors, status: :unprocessable_entity }
end
end
end
# DELETE /shopping_lists/1
# DELETE /shopping_lists/1.json
def destroy
#shopping_list.destroy
respond_to do |format|
format.html { redirect_to shopping_lists_url, notice: 'Shopping list was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_shopping_list
#shopping_list = ShoppingList.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
private def shopping_list_params
params.require(:shopping_list).permit(:name)
end
end
EDIT: sorry I forgot the test-controller: shopping_lists_controller_test
require 'test_helper'
class ShoppingListsControllerTest < ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers
include Warden::Test::Helpers
setup do
#drogerieShoppingList = shopping_lists(:shopping_list_drogerie)
#heiko = users(:user_heiko)
#heikoAppointment = appointments(:appointment_heiko)
end
test "should get index" do
login_as(#heiko)
#heiko.confirmed_at = Time.now
get shopping_lists_url
assert_response :success
end
test "should get new" do
login_as(#heiko)
#heiko.confirmed_at = Time.now
get new_shopping_list_url
assert_response :success
end
test "should create shopping_list" do
login_as(#heiko)
#heiko.confirmed_at = Time.now
assert_difference('ShoppingList.count') do
#post shopping_lists_url, params: { shopping_list: #drogerieShoppingList.attributes, user_id: #heiko.id, appointment: #heikoAppointment }
post shopping_lists_url, params: { shopping_list: #drogerieShoppingList.attributes }
end
assert_redirected_to shopping_list_url(ShoppingList.last)
end
test "should show shopping_list" do
login_as(#heiko)
#heiko.confirmed_at = Time.now
get shopping_list_url(#drogerieShoppingList)
assert_response :success
end
test "should get edit" do
login_as(#heiko)
#heiko.confirmed_at = Time.now
get edit_shopping_list_url(#drogerieShoppingList)
assert_response :success
end
test "should update shopping_list" do
login_as(#heiko)
#heiko.confirmed_at = Time.now
patch shopping_list_url(#drogerieShoppingList), params: { shopping_list: {name: 'WochenendEinkauf' } }
assert_redirected_to shopping_list_url(#drogerieShoppingList)
end
test "should destroy shopping_list" do
login_as(#heiko)
#heiko.confirmed_at = Time.now
assert_difference('ShoppingList.count', -1) do
delete shopping_list_url(#drogerieShoppingList)
end
assert_redirected_to shopping_lists_url
end
end
The problem isn't about the number of parameters.
Add the controller test code, because there's a test case that fails.
But when I look closer to your controller, the create method didn't actually created a #schopping_list. It just tries to save a #shopping_list variable which can easily be a nil.
UPDATE:
There seems to be two issues:
#create action in controller
The #sopping_list isn't initialized at all, You have to build the #shopping_list model before saving it. Like this:
def create
#shopping_list = SoppingList.new(shopping_list_params)
respond_to do |format|
if #shopping_list.save
...
Don't know whether the name field is the only field required to create a SoppingList model. As I see you've permitted only that one:
params.require(:shopping_list).permit(:name)

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.

Rspec - controller test error - Paperclip::AdapterRegistry::NoHandlerError: No handler found for "#<File:0x531beb0>"

I asked about my Rspec test as follow.
Rspec - RuntimeError: Called id for nil, which would mistakenly be 4
On the same code (Rspec test for "items_controller.rb"), I am trying to make the test for "PUT update". However I got the error "Paperclip::AdapterRegistry::NoHandlerError: No handler found for "#".
My Rspec test is as follow. Honestly, I guess that the cause of this fail is ""photo" => File.new(Rails.root + 'app/assets/images/rails.png')" on "let(:valid_attributes)". However, I tried several ways but I couldn't fix.
By the way, my rails version is "Rails 3.2.14". Then I tried following post, but also couldn't.
Can't figure out what's causing my tests to fail
The error is as follows.
......F....
Failures:
1) ItemsController PUT update could not update successfully
Failure/Error: put :update, {:id => item.to_param, :item => valid_attributes}, valid_session
Paperclip::AdapterRegistry::NoHandlerError:
No handler found for "#<File:0x5d4c548>"
# ./app/controllers/items_controller.rb:110:in `block in update'
# ./app/controllers/items_controller.rb:108:in `update'
# ./spec/controllers/items_controller_spec.rb:95:in `block (3 levels) in <top (required)>'
Finished in 1.75 seconds
11 examples, 1 failure
Failed examples:
rspec ./spec/controllers/items_controller_spec.rb:91 # ItemsController PUT update could not update successfully
Randomized with seed 40912
My Rspec test is as follows.
require 'spec_helper'
require 'date'
describe ItemsController do
let(:valid_attributes) { {
"days" => "1",
"hours" => "1",
"minutes" => "1",
"name"=>"HogeHoge" ,
"category" => "Gift",
"min_bid_price" => "100.0",
"description" => "HogeHoge",
"photo" => File.new(Rails.root + 'app/assets/images/rails.png')
} }
let(:valid_session) { {} }
it "returns http success" do
get "index"
response.should be_success
end
it "returns http success" do
get "new"
response.should be_success
end
describe "POST create" do
it "" do
#declare the objects and stubs
current_user = User.new(id:'1')
current_user.save
#"current_user=(user)" function on controller
controller.current_user = current_user
#auction
auction = Auction.new(id:'1',highest_bid_id:'1', extend_bit:'1')
auction.save
Auction.stub(:find_by_id).and_return(auction)
#bid
bid = Bid.new(auction_id:'1',amount:'150.0')
bid.save
Bid.stub(:find_by_id).and_return(bid)
#item
item = Item.new(id:'1',auction_id:'1',min_bid_price:'100.0')
item.save
Item.stub(:find_by_id).and_return(item)
date = DateTime.now
post :create, {:item => {'id' => '2','days'=>'1','hours'=>'1','minutes'=>'1','created_at'=>date}}
response.should be_success
end
end
describe "GET index" do
it "assigns all items as #items" do
item = Item.create! valid_attributes
get :index, {}, valid_session
assigns(:items).should eq([item])
end
end
describe "GET show" do
it "assigns the requested item as #item" do
item = Item.create! valid_attributes
get :show, {:id => item.to_param}, valid_session
assigns(:item).should eq(item)
end
end
describe "GET new" do
it "assigns a new item as #item" do
get :new, {}, valid_session
assigns(:item).should be_a_new(Item)
end
end
describe "GET edit" do
it "assigns the requested item as #item" do
item = Item.create! valid_attributes
get :edit, {:id => item.to_param}, valid_session
assigns(:item).should eq(item)
end
end
describe "PUT update" do
it "could not update successfully" do
item = Item.create! valid_attributes
# Trigger the behavior that occurs when invalid params are submitted
Item.any_instance.stub(:save).and_return(false)
put :update, {:id => item.to_param, :item => valid_attributes}, valid_session
assigns(:item).should eq(item)
response.should redirect_to(#item)
end
it "could not update successfully" do
item = Item.create! valid_attributes
# Trigger the behavior that occurs when invalid params are submitted
Item.any_instance.stub(:save).and_return(false)
put :update, {:id => item.to_param, :item => { }}, valid_session
response.should render_template("edit")
end
end
describe "DELETE destroy" do
it "destroys the requested item" do
item = Item.create! valid_attributes
expect {
delete :destroy, {:id => item.to_param}, valid_session
}.to change(Item, :count).by(-1)
end
it "redirects to the items list" do
item = Item.create! valid_attributes
delete :destroy, {:id => item.to_param}, valid_session
response.should redirect_to(items_url)
end
end
end
My "items_controller.rb" is as follw.
require 'timers'
class ItemsController < ApplicationController
#instance of current user
def current_user=(user)
#current_user ||= user
end
def extendtimer
Auction.find_by_id(#auction_id).update_attributes(:extend_bit => 0)
#exp = Auction.find_by_id(#auction_id).exp_time + 2.minutes
Auction.find_by_id(#auction_id).update_attributes(:exp_time => #exp)
#min = Item.find_by_id(#item_id).minutes + 2
Item.find_by_id(#item_id).update_attributes(:minutes => #min)
#timer2 = Timers.new
#extend_timer = #timer2.after(120){ buy }
#timer2.wait
end
def buy
if Auction.find_by_id(#auction_id).extend_bit == 1
extendtimer
else
if Auction.find_by_id(#auction_id).highest_bid_id != 0
Item.find_by_auction_id(#auction_id).update_attributes(:sold => 1, :sold_to => Bid.find_by_id(Auction.find_by_id(#auction_id).highest_bid_id).user_id )
MyMailer.auction_winner_email(Auction.find_by_id(#auction_id)).deliver
else
Item.find_by_auction_id(#auction_id).update_attributes(:sold => 0, :sold_to => 0 )
MyMailer.no_bids_email(Auction.find_by_id(#auction_id)).deliver
end
#t1.join
end
end
def index
#items = Item.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #items }
end
end
# GET /items/1
# GET /items/1.json
def show
#item = Item.find(params[:id])
respond_to do |format|
#format.html # show.html.erb
format.html { render layout: (request.headers["X-Requested-With"] != 'XMLHttpRequest') }
format.json { render json: #item }
end
end
# GET /items/new
# GET /items/new.json
def new
#item = Item.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #item }
end
end
# GET /items/1/edit
def edit
#item = Item.find(params[:id])
end
# POST /items
# POST /items.json
def create
#item = Item.new(params[:item])
#item.user_id = current_user.id
respond_to do |format|
if #item.save
format.html { redirect_to #item, notice: 'Item was successfully created.' }
format.json { render json: #item, status: :created, location: #item }
else
format.html { render action: "new" }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
#elapsed_seconds =(((params[:item][:days].to_i * 24)+params[:item][:hours].to_i)*60+params[:item][:minutes].to_i)*60
#auction = Auction.create(:item_id => #item.id, :highest_bid_id => 0, :exp_time => #item.created_at+ #elapsed_seconds.seconds, :suspend => 0, :user_id => #current_user.id, :extend_bit => 0 )
#item.update_attributes(:auction_id => #auction.id)
#item_id = #item.id
#auction_id = #auction.id
#t1 = Thread.new{
#timer = Timers.new
#bid_timer = #timer.after(#elapsed_seconds){
if Auction.find_by_id(#auction_id).suspend != 1
buy
end
}
#timer.wait
}
end
# PUT /items/1
# PUT /items/1.json
def update
#item = Item.find(params[:id])
respond_to do |format|
if #item.update_attributes(params[:item])
format.html { redirect_to #item, notice: 'Item was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /items/1
# DELETE /items/1.json
def destroy
#item = Item.find(params[:id])
#item.destroy
respond_to do |format|
format.html { redirect_to items_url }
format.json { head :no_content }
end
end
end
I would like to have someone's advice. Thank you in advance.
Try using Rack::Test::UploadedFile instead of File.new
require 'rack/test'
Rack::Test::UploadedFile.new('fixtures/test_file.png', 'image/png')
im pretty sure your problem is with the form_for in the view,
try something like this:
<%= form_for #restaurante, :html => { :multipart => true } do |form| %>
Nome:<%= form.text_field :nome%>
Endereço:<%= form.text_field :endereco %>
Especialidade:<%= form.text_field :especialidade %>
Foto:<%= form.file_field :foto %>
<%= form.submit 'create'%>
<% end %>
Make sure it's multipart/form-data in the test.
I have a helper method for this.
module Support
module Acceptance
module ClassMethods
def multipart_form_data!
header 'Accept', 'application/json'
header 'Content-Type', 'multipart/form-data'
end
end
end
end

Resources