这可能看似多余,因为类似的问题已经被问到here和here,但我还没有找到解决方案。
我正在运行RSpec来测试:更新api。当我运行RSpec时,它在我的第一次测试时显示No Route Matches。我需要的是对未经身份验证的用户进行have_http_status(401)测试。 Rails无法弄清楚路由。 这是错误所说的:
Failures:
1) PostsController unauthenticated user PUT update returns http unauthenticated
Failure/Error: put :update, topic_id: my_topic.id, post_id: my_post.id, post: {title: my_post.title, body: my_post.body}
ActionController::UrlGenerationError:
No route matches {:action=>"update", :controller=>"posts", :post=>{:title=>"Xdiwbu zuitsom prubmlhd oxmgtkb swphb ukije salhvk.", :body=>"Pjlb ywlzqv igdesqmw oqjgy mrwpye ujierxtn owqxbvt. Wzxu sjcikthg xare tcawzx tedmiqwf lewab. Twkeoun mos ophta fvae krmnsqe. Jxefyo ncd agj ieyanvt uehazwnk mtsi fbsm."}, :post_id=>"1", :topic_id=>"1"}
# ./spec/api/v1/controllers/posts_controller_spec.rb:11:in `block (3 levels) in <top (required)>'
这是RSpec(spec / api / v1 / controllers / posts_controller_spec.rb)
require 'rails_helper'
RSpec.describe Api::PostsController, type: :controller do
let(:my_user) { create(:user) }
let(:my_topic) { create(:topic) }
let(:my_post) { create(:post, topic: my_topic, user: my_user) }
context "unauthenticated user" do
it "PUT update returns http unauthenticated" do
put :update, topic_id: my_topic.id, post_id: my_post.id, post: {title: my_post.title, body: my_post.body}
expect(response).to have_http_status(401)
end
...
以下是路线:
namespace :api do
namespace :v1 do
resources :users, only: [:index, :show, :create, :update]
resources :topics, except: [:edit, :new] do
resources :posts, only: [:update, :create, :destroy]
end
end
end
以下是测试的第一部分:
class Api::V1::PostsController < Api::V1::BaseController
before_action :authenticate_user, except: [:index, :show]
before_action :authorize_user, except: [:index, :show]
def update
post = Post.find(params[:id])
if post.update_attributes(post_params)
render json: post.to_json, status: 200
else
render json: {error: "Post update failed", status: 400}, status: 400
end
end
...
无论我改变RSpec,我都无法让它与路线相匹配。你们介意帮忙吗?
谢谢!
答案 0 :(得分:3)
有两件事让我感到高兴。
1:控制器本身在Api::V1
下被命名空间。但是,规范中的控制器仅在Api
下被命名空间。这应该更新以匹配。
2:如果您运行rake routes
,您会注意到这样的一行:
PUT /api/v1/topics/:topic_id/posts/:id(.:format) api/v1/posts#update
。
注意在该消息中:
之后给出的名称非常重要。在这里,它说明主题的ID应该作为topic_id
提供给控制器,并且帖子的ID应该只提供id
。如果您将put
语句修改为更像put :update, topic_id: my_topic.id, id: my_post.id, post: {title: my_post.title, body: my_post.body}
的内容,则应该有效。