Ruby on rails 4 已验证的路由不适用于Rspec测试
下面我将介绍如何在Rails 4应用程序的路由中设置身份验证 这是我的routes.rb文件:Ruby on rails 4 已验证的路由不适用于Rspec测试,ruby-on-rails-4,rspec,Ruby On Rails 4,Rspec,下面我将介绍如何在Rails 4应用程序的路由中设置身份验证 这是我的routes.rb文件: Rails.application.routes.draw do devise_for :employees, :controllers => { registrations: 'employees/registrations' } devise_for :clients authenticate :employee do resources :quotation_re
Rails.application.routes.draw do
devise_for :employees, :controllers => { registrations: 'employees/registrations' }
devise_for :clients
authenticate :employee do
resources :quotation_requests, only: [:show, :edit,:index, :update, :destroy]
end
resources :quotation_requests, only: [:new, :create]
get '/dashboard' => 'dashboard#show', as: 'show_dashboard'
root to: 'home#index'
end
这是我的报价单\u请求\u控制器\u spec.rb文件:
require 'rails_helper'
RSpec.describe QuotationRequestsController, type: :controller do
describe "GET index" do
it "renders :index template" do
get :index
expect(response).to render_template(:index)
end
it "assigns quotation requests to template" do
quotation_requests = FactoryGirl.create_list(:quotation_request, 3)
get :index
expect(assigns(:quotation_requests)).to match_array(quotation_requests)
end
end
describe "GET edit" do
let(:quotation_request) { FactoryGirl.create(:quotation_request)}
it "renders :edit template" do
get :edit, id: quotation_request
expect(response).to render_template(:edit)
end
it "assigns the requested quotation request to template" do
get :edit, id: quotation_request
expect(assigns(:quotation_request)).to eq(quotation_request)
end
end
describe "PUT update" do
let(:quotation_request) { FactoryGirl.create(:quotation_request)}
context "valid data" do
new_text = Faker::Lorem.sentence(word_count=500)
let(:valid_data) { FactoryGirl.attributes_for(:quotation_request, sample_text: new_text)}
it "redirects to quotation_request#showtemplate" do
put :update, id: quotation_request, quotation_request: valid_data
expect(response).to redirect_to(quotation_request)
end
it "updates quotation request in the database" do
put :update, id: quotation_request, quotation_request: valid_data
quotation_request.reload #need to reload the object because we have just updated it in the database so need to get the new values
expect(quotation_request.sample_text).to eq(new_text)
end
end
context "invalid data" do
let(:invalid_data) { FactoryGirl.attributes_for(:quotation_request, sample_text: "", number_of_words: 400)}
it "renders the :edit template" do
put :update, id: quotation_request, quotation_request: invalid_data
expect(response).to render_template(:edit)
end
it "does not update the quotation_request in the database" do
put :update, id: quotation_request, quotation_request: invalid_data
quotation_request.reload
expect(quotation_request.number_of_words).not_to eq(400)
end
end
end
describe "GET new", new: true do
it "renders :new template" do
get :new
expect(response).to render_template(:new)
end
it "assigns new QuotationRequest to @quotation_request" do
get :new
expect(assigns(:quotation_request)).to be_a_new(QuotationRequest)
end
end
describe "GET show" do
#this test requires that there be a quotation request in the database
let(:quotation_request) { FactoryGirl.create(:quotation_request) }
context 'invalid request' do
it "does not render :show template if an employee or client is not signed in" do
#setup
quotation_request = create(:quotation_request)
#exercise
get :show, id: quotation_request
#verification
expect(response).to_not render_template(:show)
end
end
context 'valid request' do
sign_in_proofreader
it "renders :show template if an employee or client is signed in" do
#setup
quotation_request = create(:quotation_request)
#exercise
get :show, id: quotation_request
#verification
expect(response).to render_template(:show)
end
it "assigns requested quotation_request to @quotation_request" do
get :show, id: quotation_request
expect(assigns(:quotation_request)).to eq(quotation_request)
end
end
end
describe "POST create", post: true do
context "valid data" do
let(:valid_data) {FactoryGirl.nested_attributes_for(:quotation_request)}
it "redirects to quotation_requests#show" do
post :create, quotation_request: valid_data
expect(response).to redirect_to(quotation_request_path(assigns[:quotation_request]))
end
it "creates new quotation_request in database" do
expect {
post :create, quotation_request: valid_data
}.to change(QuotationRequest, :count).by(1)
end
end
context "invalid data" do
let(:invalid_data) {FactoryGirl.nested_attributes_for(:quotation_request).merge(sample_text: 'not enough sample text')}
it "renders :new template" do
post :create, quotation_request: invalid_data
expect(response).to render_template(:new)
end
it "doesn't creates new quotation_request in database" do
expect {
post :create, quotation_request: invalid_data
}.not_to change(QuotationRequest, :count)
end
end
end
describe "DELETE destroy" do
let(:quotation_request) { FactoryGirl.create(:quotation_request) }
it "redirects to the quotation request#index" do
delete :destroy, id: quotation_request
expect(response).to redirect_to(quotation_requests_path)
end
it "delets the quotation request from the database" do
delete :destroy, id: quotation_request
expect(QuotationRequest.exists?(quotation_request.id)).to be_falsy
end
end
end
我的报价单\u请求\u controller.rb
class QuotationRequestsController < ApplicationController
# before_action :authenticate_employee!, :only => [:show]
def index
@quotation_requests = QuotationRequest.all
end
def new
@quotation_request = QuotationRequest.new
@quotation_request.build_client
end
def edit
@quotation_request = QuotationRequest.find(params[:id])
end
def create
client = Client.find_or_create(quotation_request_params[:client_attributes])
@quotation_request = QuotationRequest.new(quotation_request_params.except(:client_attributes).merge(client: client))
if @quotation_request.save
ClientMailer.quotation_request_created(client.email, @quotation_request.id).deliver_now
redirect_to @quotation_request, notice: 'Thank you.'
else
render :new
end
end
def show
@quotation_request = QuotationRequest.find(params[:id])
end
def update
@quotation_request = QuotationRequest.find(params[:id])
if @quotation_request.update(quotation_request_params)
redirect_to @quotation_request
else
render :edit
end
end
def destroy
QuotationRequest.destroy(params[:id])
redirect_to quotation_requests_path
end
private
def quotation_request_params
params.require(:quotation_request).permit(:number_of_words, :return_date, :sample_text, :client_attributes => [:first_name, :last_name, :email])
end
end
rspec测试通过。因此,出于某种原因,Rspec没有注册路由的身份验证
以下是Rspec对使用经过身份验证的路由运行的测试的输出:
QuotationRequestsController
GET index
valid request
renders :index template for signed in employee
assigns quotation requests to template
invalid request
does not render :index template without a signed in employee (FAILED - 1)
GET edit
valid request
renders :edit template with a signed in employee
assigns the requested quotation request to template
invalid request
does not render the :edit template without a signed in employee (FAILED - 2)
PUT update
valid request
valid data
redirects to quotation_request#showtemplate
updates quotation request in the database
invalid data
renders the :edit template
does not update the quotation_request in the database
invalid request
redirects user to the sign in page (FAILED - 3)
GET new
renders :new template
assigns new QuotationRequest to @quotation_request
GET show
invalid request
does not render :show template if an employee or client is not signed in (FAILED - 4)
valid request
renders :show template if an employee or client is signed in
assigns requested quotation_request to @quotation_request
POST create
valid data
redirects to quotation_requests#show
creates new quotation_request in database
invalid data
renders :new template
doesn't creates new quotation_request in database
DELETE destroy
valid request
redirects to the quotation request#index
delets the quotation request from the database
invalid request
does not delete the quotation request without a signed in employee (FAILED - 5)
Failures:
1) QuotationRequestsController GET index invalid request does not render :index template without a signed in employee
Failure/Error: expect(response).to_not render_template(:index)
Didn't expect to render index
# ./spec/controllers/quotation_requests_controller_spec.rb:43:in `block (4 levels) in <top (required)>'
# -e:1:in `<main>'
2) QuotationRequestsController GET edit invalid request does not render the :edit template without a signed in employee
Failure/Error: expect(response).to_not render_template(:edit)
Didn't expect to render edit
# ./spec/controllers/quotation_requests_controller_spec.rb:92:in `block (4 levels) in <top (required)>'
# -e:1:in `<main>'
3) QuotationRequestsController PUT update invalid request redirects user to the sign in page
Failure/Error: expect(response).to_not redirect_to(quotation_request)
Didn't expect to redirect to #<QuotationRequest:0x007fe7eb69c8c0>
# ./spec/controllers/quotation_requests_controller_spec.rb:182:in `block (4 levels) in <top (required)>'
# -e:1:in `<main>'
4) QuotationRequestsController GET show invalid request does not render :show template if an employee or client is not signed in
Failure/Error: expect(response).to_not render_template(:show)
Didn't expect to render show
# ./spec/controllers/quotation_requests_controller_spec.rb:217:in `block (4 levels) in <top (required)>'
# -e:1:in `<main>'
5) QuotationRequestsController DELETE destroy invalid request does not delete the quotation request without a signed in employee
Failure/Error: expect(QuotationRequest.exists?(quotation_request.id)).to be_truthy
expected: truthy value
got: false
# ./spec/controllers/quotation_requests_controller_spec.rb:361:in `block (4 levels) in <top (required)>'
# -e:1:in `<main>'
Finished in 2.11 seconds (files took 1.75 seconds to load)
23 examples, 5 failures
Failed examples:
rspec ./spec/controllers/quotation_requests_controller_spec.rb:37 # QuotationRequestsController GET index invalid request does not render :index template without a signed in employee
rspec ./spec/controllers/quotation_requests_controller_spec.rb:83 # QuotationRequestsController GET edit invalid request does not render the :edit template without a signed in employee
rspec ./spec/controllers/quotation_requests_controller_spec.rb:171 # QuotationRequestsController PUT update invalid request redirects user to the sign in page
rspec ./spec/controllers/quotation_requests_controller_spec.rb:208 # QuotationRequestsController GET show invalid request does not render :show template if an employee or client is not signed in
rspec ./spec/cont
QuotationRequestsController
获取索引
有效请求
呈现:已登录员工的索引模板
将报价请求分配给模板
无效请求
不呈现:没有登录员工的索引模板(失败-1)
编辑
有效请求
呈现:使用已登录的员工编辑模板
将请求的报价请求分配给模板
无效请求
在没有登录员工的情况下不呈现:编辑模板(失败-2)
放置更新
有效请求
有效数据
重定向到报价单#请求#显示模板
更新数据库中的报价请求
无效数据
渲染:编辑模板
不更新数据库中的报价单请求
无效请求
将用户重定向到登录页面(失败-3)
获得新的
渲染:新模板
将新QuotationRequest分配给@quotation\u请求
表演
无效请求
不呈现:如果员工或客户未登录,则显示模板(失败-4)
有效请求
呈现:如果员工或客户已登录,则显示模板
将请求的报价单请求分配给@QUOTE\u请求
后期创建
有效数据
重定向到报价单#请求#显示
在数据库中创建新的报价单请求
无效数据
渲染:新模板
不在数据库中创建新的报价单请求
删除销毁
有效请求
重定向到报价请求#索引
从数据库中删除报价请求
无效请求
在没有登录员工的情况下不删除报价请求(失败-5)
失败:
1) QuotationRequestsController获取索引无效请求未呈现:没有登录员工的索引模板
失败/错误:预期(响应)。不呈现模板(:索引)
没想到会呈现索引
#./spec/controllers/quote\u requests\u controllers\u spec.rb:43:in‘block(4级)in’
#-e:1:in`'
2) QuotationRequestsController获取编辑无效请求不会在没有登录员工的情况下呈现:编辑模板
失败/错误:预期(响应)。不呈现模板(:编辑)
没想到会渲染编辑
#./spec/controllers/quote\u requests\u controllers\u spec.rb:92:in‘block(4级)in’
#-e:1:in`'
3) QuotationRequestsController放置更新无效请求将用户重定向到登录页面
失败/错误:预期(响应)。不重定向到(报价请求)
没想到会重定向到#
#./spec/controllers/quote\u requests\u controller\u spec.rb:182:in`block(4级)in'
#-e:1:in`'
4) QuotationRequestsController获取显示无效请求不呈现:如果员工或客户未登录,则显示模板
失败/错误:预期(响应)。不呈现模板(:show)
没想到会有这样的表演
#./spec/controllers/quote\u requests\u controller\u spec.rb:217:in`block(4级)in'
#-e:1:in`'
5) QuotationRequestsController删除销毁无效请求在没有登录员工的情况下不会删除报价请求
失败/错误:期望(QuotationRequest.exists?(quotation\u-request.id))。真实
期望值:真实值
得了:错
#./spec/controllers/quote\u requests\u controllers\u spec.rb:361:in‘block(4级)in’
#-e:1:in`'
在2.11秒内完成(加载文件需要1.75秒)
23例,5次失败
失败的示例:
rspec./spec/controllers/quote_requests_controller_spec.rb:37#quotationrequests controller获取索引无效请求未呈现:没有登录员工的索引模板
rspec./spec/controllers/quote_requests_controller_spec.rb:83#quotationrequests controller GET edit无效请求在没有登录员工的情况下不会呈现:edit模板
rspec./spec/controllers/quote_-requests_-controller_-spec.rb:171#quotationrequests控制器放置更新无效请求将用户重定向到登录页面
rspec./spec/controllers/quote_requests_controller_spec.rb:208#quotationrequests controller GET show无效请求不呈现:如果员工或客户未登录,则显示模板
rspec./spec/cont
为什么我编写的路由在Rspec测试中不起作用?我想您正在rails应用程序中使用它。
Rspec rails为您设置了许多方便的方法,但它也引入了一些黑魔法,这可能会导致一些意想不到的结果,比如这样
控制器规格注释中对此进行了解释:
# Supports a simple DSL for specifying behavior of ApplicationController.
# Creates an anonymous subclass of ApplicationController and evals the
# `body` in that context. Also sets up implicit routes for this
# controller, that are separate from those defined in "config/routes.rb".
我想这里的逻辑是,控制器功能与路由不同,应该单独测试(而且rspec rails确实提供了一个路由测试组),因此我们不需要控制器规格的路由,这意味着您应该能够在不设置路由的情况下测试控制器
在我的观点中,为未经身份验证的用户测试重定向更像是一种集成测试,因为它需要应用程序的多个部分协同工作,因此不应该在控制器上下文中进行测试,而应该在一些黑盒测试中作为一项功能进行测试
您可以通过将集成测试放在这些目录之一spec/requests、spec/api和spec/integration
中,或者通过使用
RSpec.describe "Something", type: :request do
或者将其放置在spec/features
中,或者将类型声明为
RSpec.describe "Something", type: :feature do
取决于要测试重定向的级别(意思是:仅测试请求-响应)
RSpec.describe "Something", type: :feature do