在 Rails 4 Controller 中使用时处理关注点测试的最佳方法是什么?假设我有一个微不足道的问题Citations
。
module Citations
extend ActiveSupport::Concern
def citations ; end
end
测试中的预期行为是任何包含此问题的 Controller 都会获得此引用
端点。
class ConversationController < ActionController::Base
include Citations
end
简单。
ConversationController.new.respond_to? :yelling #=> true
但是单独测试这个问题的正确方法是什么?
class CitationConcernController < ActionController::Base
include Citations
end
describe CitationConcernController, type: :controller do
it 'should add the citations endpoint' do
get :citations
expect(response).to be_successful
end
end
不幸的是,这失败了。
CitationConcernController
should add the citations endpoint (FAILED - 1)
Failures:
1) CitationConcernController should add the citations endpoint
Failure/Error: get :citations
ActionController::UrlGenerationError:
No route matches {:controller=>"citation_concern", :action=>"citations"}
# ./controller_concern_spec.rb:14:in `block (2 levels) in <top (required)>'
这是一个人为的例子。在我的应用程序中,我收到了不同的错误。
RuntimeError:
@routes is nil: make sure you set it in your test's setup method.
最佳答案
您会发现许多建议告诉您使用共享示例并在包含的 Controller 范围内运行它们。
我个人认为它太过分了,更喜欢单独执行单元测试,然后使用集成测试来确认我的 Controller 的行为。
方法 1:无需路由或响应测试
创建一个假 Controller 并测试其方法:
describe MyControllerConcern do
before do
class FakesController < ApplicationController
include MyControllerConcern
end
end
after do
Object.send :remove_const, :FakesController
end
let(:object) { FakesController.new }
it 'my_method_to_test' do
expect(object).to eq('expected result')
end
end
方法2:测试响应
当您关注的是路由或者您需要测试响应、渲染等时...您需要使用匿名 Controller 运行测试。这允许您访问所有与 Controller 相关的 rspec 方法和帮助器:
describe MyControllerConcern, type: :controller do
controller(ApplicationController) do
include MyControllerConcern
def fake_action; redirect_to '/an_url'; end
end
before do
routes.draw {
get 'fake_action' => 'anonymous#fake_action'
}
end
describe 'my_method_to_test' do
before do
get :fake_action
end
it do
expect(response).to redirect_to('/an_url')
end
end
end
如您所见,我们使用 controller(ApplicationController)
定义匿名 Controller 。如果您的测试涉及 ApplicationController
之外的其他类,您将需要对此进行调整。
此外,为了使其正常工作,您必须在 spec_helper.rb 文件中配置以下内容:
config.infer_base_class_for_anonymous_controllers = true
注意:不断测试您的问题是否包含在内
测试您的关注类是否包含在目标类中也很重要,一行就足够了:
describe SomeTargetedController do
it 'includes MyControllerConcern' do
expect(SomeTargetedController.ancestors.include? MyControllerConcern).to be(true)
end
end
关于ruby-on-rails - 如何在 Rails 4 中测试 Controller 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22055889/