我正在遵循Michael Hartl's教程,第10章。尝试进行UsersControllerTest#test_should_redirect_edit_when_logged_in_as_wrong_user
时,测试get edit_user_path(@user)
失败。
get edit_user_path(@user)
ActionController::UrlGenerationError: No route matches {:action=>"/users/762146111/edit", :controller=>"users"}
from /Users/cello/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/actionpack-5.1.4/lib/action_dispatch/journey/formatter.rb:55:in `generate'
但是:
Rails.application.routes.recognize_path '/users/762146111/edit', method: :get
=> {:controller=>"users", :action=>"edit", :id=>"762146111"}
下面是可能存在错误的代码( Rails 5.1.4 )。
routes.rb
Rails.application.routes.draw do
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
post 'signup', to: 'users#create'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
get 'sessions/new'
resources :users
end
users_controller_test.rb
require 'test_helper'
class UsersControllerTest < ActionController::TestCase
def setup
@user = users(:michael)
@other_user = users(:archer)
end
test 'should redirect edit when logged in as wrong user' do
log_in_as(@other_user)
get edit_user_path(@user)
assert flash.empty?
assert_redirected_to root_url
end
end
users_controller.rb
class UsersController < ApplicationController
before_action :logged_in_user, only: [:edit, :update]
before_action :correct_user, only: [:edit, :update]
def edit
@user = User.find(params[:id])
end
private
def logged_in_user
unless logged_in?
flash[:danger] = 'Please log in.'
redirect_to login_url
end
end
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
end
答案 0 :(得分:1)
本教程定义了集成测试(继承自ActionDispatch::IntegrationTest
),而您上面的代码定义了 Controller Test (继承自{{1} }。
ActionController::TestCase
是控制器测试的正确语法,因为它绕过URL识别并直接指定get :edit, ...
。这令人困惑,并且是现在不鼓励使用控制器测试而推荐使用集成测试的几个原因之一,而这可能正是您要创建的。
为此,请更改:
:action
收件人:
class UsersControllerTest < ActionController::TestCase
(请注意,本教程在将class UsersControllerTest < ActionDispatch::IntegrationTest
和放入ActionDispatch::IntegrationTest
的测试中都使用tests/integration/
作为基类,这有些令人困惑。 )
答案 1 :(得分:0)
您不能在规范中将直接url与'get'方法一起使用。
以您的规格而不是
get edit_user_path(@user)
使用
get :edit, params: { id: @user.id }
与
相同patch user_path(@user)
改为使用patch :update