我正在创建一个人们可以创造就业机会的应用程序,但只能破坏他们创造的工作。我知道我的应用程序可以让人们破坏工作,因为我可以手动测试它,但RSpec却落后了。
以下是相关测试:
jobs_controller_spec.rb
require 'spec_helper'
describe JobsController do
let!(:user) { FactoryGirl.create(:user) }
let!(:job) { FactoryGirl.create(:job, user: user) }
let!(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
let!(:wrong_job) { FactoryGirl.create(:job, user: wrong_user) }
[...]
describe "correct user control" do
before { sign_in user }
describe "users can only delete their own jobs" do
it "should not change job count" do
expect do
delete :destroy, id: wrong_job.id
end.to_not change(Job, :count)
end
end
describe "users can delete their own jobs" do
it "should decrease job count" do
expect do
delete :destroy, id: job.id
end.to change(Job, :count).by(-1)
end
end
end
end
这是失败的测试:
1) JobsController correct user control users can delete their own jobs should decrease job count
Failure/Error: expect do
count should have been changed by -1, but was changed by 0
# ./spec/controllers/jobs_controller_spec.rb:41:in `block (4 levels) in <top (required)>'
jobs_controller.rb
class JobsController < ApplicationController
skip_before_action :require_signin, only: [:index, :show]
skip_before_action :correct_user, only: [:index, :show, :new, :create]
before_action :set_job, only: [:show, :edit, :update, :destroy]
[...]
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
end
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :require_signin
before_filter :correct_user
include SessionsHelper
private
def require_signin
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in."
end
end
def correct_user
@job = current_user.jobs.find_by(id: params[:id])
redirect_to root_url if @job.nil?
end
end
佣金路线
Prefix Verb URI Pattern Controller#Action
jobs GET /jobs(.:format) jobs#index
POST /jobs(.:format) jobs#create
new_job GET /jobs/new(.:format) jobs#new
edit_job GET /jobs/:id/edit(.:format) jobs#edit
job GET /jobs/:id(.:format) jobs#show
PATCH /jobs/:id(.:format) jobs#update
PUT /jobs/:id(.:format) jobs#update
DELETE /jobs/:id(.:format) jobs#destroy
[...]
答案 0 :(得分:1)
正如Peter Alfvin指出的那样,如果控制器规范中存在身份验证,则必须设置会话并将其作为第三个参数传递,例如:
...
let(:some_user) { User.create }
def valid_session
{ user_id: some_user.id }
end
describe "DELETE destroy" do
it "destroys the requested job" do
job = Job.create! valid_attributes
expect {
delete :destroy, { :id => job.to_param }, valid_session
}.to change(Job, :count).by(-1)
end
end
答案 1 :(得分:0)
解决方案是将no_capybara: true
传递给sign_in
。 Capybara不适用于控制器测试,因此不能使用水豚来管理登录过程。
感谢Patrick Brinich-Langlois的解决方案。