【发布时间】:2016-09-20 21:31:54
【问题描述】:
我正在通过为现有项目编写规范来学习 RSpec。我在使用多态资源 Notes 的控制器规范时遇到问题。几乎任何其他模型都可以像这样与 Notes 建立关系:has_many :notes, as: :noteable
此外,该应用程序是多租户的,每个帐户可以有多个用户。每个帐户由:slug 访问,而不是 URL 中的:id。所以我的多租户、多态路由看起来像这样:
# config/routes.rb
...
scope ':slug', module: 'accounts' do
...
resources :customers do
resources :notes
end
resources :products do
resources :notes
end
end
这会为 :new 操作生成类似这样的路由
new_customer_note GET /:slug/customers/:customer_id/notes/new(.:format) accounts/notes#new
new_product_note GET /:slug/products/:product_id/notes/new(.:format) accounts/notes#new
现在开始测试问题。首先,这是我如何测试其他非多态控制器的示例,例如invitations_controller:
# from spec/controllers/accounts/invitation_controller_spec.rb
require 'rails_helper'
describe Accounts::InvitationsController do
describe 'creating and sending invitation' do
before :each do
@owner = create(:user)
sign_in @owner
@account = create(:account, owner: @owner)
end
describe 'GET #new' do
it "assigns a new Invitation to @invitation" do
get :new, slug: @account.slug
expect(assigns(:invitation)).to be_a_new(Invitation)
end
end
...
end
当我尝试使用类似的方法来测试多态 notes_controller 时,我感到困惑 :-)
# from spec/controllers/accounts/notes_controller_spec.rb
require 'rails_helper'
describe Accounts::NotesController do
before :each do
@owner = create(:user)
sign_in @owner
@account = create(:account, owner: @owner)
@noteable = create(:customer, account: @account)
end
describe 'GET #new' do
it 'assigns a new note to @note for the noteable object' do
get :new, slug: @account.slug, noteable: @noteable # no idea how to fix this :-)
expect(:note).to be_a_new(:note)
end
end
end
在这里,我只是在前面的块中创建了一个客户作为@noteable,但它也可以是一个产品。当我运行 rspec 时,我收到此错误:
No route matches {:action=>"new", :controller=>"accounts/notes", :noteable=>"1", :slug=>"nicolaswisozk"}
我知道问题出在哪里,但我就是不知道如何处理 URL 的动态部分,例如 /products/ 或 /customers/。
任何帮助表示赞赏:-)
更新:
按照以下要求将get :new 行更改为
get :new, slug: @account.slug, customer_id: @noteable
这会导致错误
Failure/Error: expect(:note).to be_a_new(:note)
TypeError:
class or module required
# ./spec/controllers/accounts/notes_controller_spec.rb:16:in `block (3 levels) in <top (required)>'
规范中的第 16 行是:
expect(:note).to be_a_new(:note)
这可能是因为我的 notes_controller.rb 中的 :new 操作不仅仅是 @note = Note.new,而是像这样在 @noteable 上初始化一个新 Note?:
def new
@noteable = find_noteable
@note = @noteable.notes.new
end
【问题讨论】:
标签: ruby-on-rails rspec multi-tenant polymorphic-associations