[英]rails namespaced controller test in rspec
My specs working fine in general, but when I try to test my nested controllers I get a weird error. 我的规格总体上可以正常工作,但是当我尝试测试嵌套控制器时,出现一个奇怪的错误。 So this code pattern
subject(:create_action) { xhr :post, :create, post_id: post.id, post_comment: attributes_for(:post_comment, post_id: post.id, user: @user) }
works fine with my controllers that are not nested, but here for my namespaced controller the test it "saves the new task in the db
raises the following error: 因此,此代码模式
subject(:create_action) { xhr :post, :create, post_id: post.id, post_comment: attributes_for(:post_comment, post_id: post.id, user: @user) }
在我不兼容的控制器上正常工作嵌套,但是对于我的命名空间控制器,此处的测试it "saves the new task in the db
会引发以下错误:
1) Posts::PostCommentRepliesController when user is logged in POST create with valid attributes saves the new task in the db
Failure/Error: subject(:create_action) { xhr :post, :create, post_comment_id: post_comment.id, post: attributes_for(:post_comment_reply, post_comment: post_comment, user: @user) }
ArgumentError:
wrong number of arguments (4 for 0)
What should I do to make this work? 我应该怎么做才能使这项工作? As you see I put my
post_comments_controller_spec.rb
in the specs/controllers/posts
folder and require posts/post_comments_controller
, but it doesn't help. 如您所见,我将我的
post_comments_controller_spec.rb
放在specs/controllers/posts
文件夹中,并要求posts/post_comments_controller
,但这无济于事。
routes.rb routes.rb
resources :posts do
resources :post_comments, only: [:create, :update, :destroy, :show], module: :posts
end
spec/controllers/posts/post_comments_controller_spec.rb 规格/控制器/帖子/post_comments_controller_spec.rb
require "rails_helper"
require "posts/post_comments_controller"
describe Posts::PostCommentsController do
describe "when user is logged in" do
before(:each) do
login_user
end
it "should have a current_user" do
expect(subject.current_user).to_not eq(nil)
end
describe "POST create" do
let!(:profile) { create(:profile, user: @user) }
let!(:post) { create(:post, user: @user) }
context "with valid attributes" do
subject(:create_action) { xhr :post, :create, post_id: post.id, post_comment: attributes_for(:post_comment, post_id: post.id, user: @user) }
it "saves the new task in the db" do
expect{ create_action }.to change{ PostComment.count }.by(1)
end
end
end
end
end
This is a slightly weird bug. 这是一个有点奇怪的错误。 In short, your
let!(:post) { ... }
ended up overwriting a method called post
on the example group that is used to issue a post request. 总之,你
let!(:post) { ... }
最后重写调用方法post
所使用发出一个POST请求的例子组。
This happened because when you define a let
within a describe
, RSpec defines you a method of the same name within the given example group . 发生这种情况的原因是,当您在
describe
定义let
,RSpec会在给定的示例组中为您定义一个名称相同的方法 。
describe Post do
let(:post) { Post.new }
it "does something" do
post.do_something
end
end
xhr
method (along with get
, post
, etc), on the other hand is a helper method for testing from Rails itself. xhr
方法 (以及get
, post
等)是从Rails本身进行测试的辅助方法。 RSpec includes this module with the helper, so that it is available in the tests. RSpec的帮助程序包括此模块 ,因此可以在测试中使用。
describe PostController, type: :controller do
let(:comment) { Comment.new }
it "can post a comment thanks to Rails TestCase::Behaviour" do
post :create, comment
# xhr :post, ... under the covers calls for post method
end
end
So the example group object had a method called post, put when you created the let, RSpec went and created you a method of that same name on the group object and thus overwriting the original (and much needed) post method. 因此,示例组对象有一个称为post的方法,当您创建let时,RSpec会在该组对象上创建一个具有相同名称的方法,从而覆盖原始的(并且非常需要)post方法。
describe PostController, type: :controller do
let(:post) { Post.new }
it "mixes up posts" do
post :create, post # post now refers to the variable, so this will cause an error
end
end
To easily resolve this issue, I would recommend naming the let(:post)
to something else, like new_post
for example. 为了轻松解决此问题,我建议将
let(:post)
命名为其他名称,例如new_post
。
describe PostController, type: :controller do
let(:new_post) { Post.new }
it "does not mix up posts" do
post :create, new_post # no more conflict
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.