Ruby on rails 使用rspec进行测试。考虑所有请求\u local=false
我正在我的应用程序中使用\u控制器:Ruby on rails 使用rspec进行测试。考虑所有请求\u local=false,ruby-on-rails,ruby,rspec,tdd,rspec-rails,Ruby On Rails,Ruby,Rspec,Tdd,Rspec Rails,我正在我的应用程序中使用\u控制器:。请考虑所有\u请求\u本地 除非Rails.application.config.confirm\u all\u请求\u local 从ActionController中营救\u::InvalidCrossOriginRequest,:with=>:render\u 404 终止 如果引发ActionController::InvalidCrossOriginRequest,则返回404。在本地环境中,它没有被提升,这有利于调试。 对于这一部分,它起作用了
。请考虑所有\u请求\u本地
除非Rails.application.config.confirm\u all\u请求\u local
从ActionController中营救\u::InvalidCrossOriginRequest,:with=>:render\u 404
终止
如果引发ActionController::InvalidCrossOriginRequest,则返回404。在本地环境中,它没有被提升,这有利于调试。
对于这一部分,它起作用了。但是我想用rspec测试一下
我试过类似的方法
描述“ActionController::InvalidCrossOriginRequest render 404”do
在{Rails.application.config.design_all_requests_local=false}之前
控制器do
def索引
raise ActionController::InvalidCrossOriginRequest
终止
终止
主题{xhr:get,:index,format::js}
它的(:status){is_expected.to eq 404}
终止
两件事。我可能没有以正确的方式提出。在本地,调用mywebsite.com/editor/fckeditor.js时会发生错误。找不到调用特定url的方法
第二个问题,before没有更改Rails.application.config.confirm\u all\u requests\u local状态
我得到:
1)ApplicationController操作控制器::InvalidCrossOriginRequest呈现404状态
失败/错误:引发ActionController::InvalidCrossOriginRequest
ActionController::InvalidCrossOriginRequest:
ActionController::InvalidCrossOriginRequest
尝试模拟它,而不是设置:
before { Rails.stub_chain('application.config.consider_all_requests_local').and_return(false) }
更多信息
此语法已弃用,因此您可以关闭弃用警告或使用新的“变通方法”
allow(object).to receive_message_chain(:one, :two, :three).and_return(:four)
expect(object.one.two.three).to eq(:four)
如前所述问题似乎是由您的
引起的,除非在课堂加载时执行了检查。这意味着在第一次加载类时,将检查应用程序配置中的值,并且设置或未设置来自
的rescue_
在最基本的解决方法中,您需要使用load
在更改设置后重新读取该文件。但是,按原样,一旦启用了rescue\u from
,再次加载文件不会导致其关闭
下一个替代方法是使用哪些委托给助手或。您可以使用此帮助器检查值并处理条件或不处理条件。但是,考虑到这看起来是您只想在非生产环境中执行的操作,您可以将两者结合起来。使用除非
确认您未在生产中,然后每次使用with检查配置
比如:
class ApplicationController < ActionController::Base
unless Rails.env.production?
rescue_from ActionController::InvalidCrossOriginRequest do
unless Rails.application.config.consider_all_requests_local
render_404
end
end
end
end
class ApplicationController
我过去也曾在配置中的rescue\u周围有一个警卫,比如:
unless Rails.application.config.consider_all_requests_local
rescue_from Exception, with: :render_error
…
end
。。。它工作得很好,直到我试图弄清楚如何让它处理错误,并在一些测试中显示漂亮的自定义错误页面(就像在生产中一样)@Aaron K有助于解释为什么不能在类定义中计算检查,而必须在实际的错误处理程序(在运行时)中进行检查。但这只解决了我的部分问题
这就是我所做的
在ApplicationController
中,如果show\u detailed\u exceptions
标志(比course\u all\u requests\u local
更合适的检查)为真,请记住重新引发任何错误。换句话说,仅当应用程序/请求配置为处理生产错误时,才进行生产错误处理;否则“通过”并重新引发错误
rescue\u from Exception,with::render\u error
从ActiveRecord::RecordNotFound中解救\u,并使用::render\u not\u
从ActionController::RoutingError中解救\u,未找到::render\u
从AbstractController::ActionNotFound中解救\u,其中::render\u未找到
def显示详细的异常情况?
#Rails.application.config.consive_all_requests_local也会将其设置为true。
请求.获取标题(“操作\调度.显示\详细\异常”)
终止
def render_not_found(异常=nil,模板='errors/not_found')
如果显示详细的异常,是否引发异常?
logger.error异常如果出现异常
呈现模板,格式:[:html],状态::未找到
终止
def render_错误(异常)
如果显示详细的异常,是否引发异常?
发送异常通知(异常)
logger.error异常
#防止AbstractController::DoubleRenderError,以防我们已经渲染了某些内容
方法(:response\u body=).super\u方法.call(nil)
回应待办事项|格式|
format.html{render'errors/internal_server_error',格式:[:html],状态::internal_server_error}
format.any{引发异常}
终止
终止
添加到spec/support/handle\u exceptions\u like\u production.rb
:
shared_context 'handle_exceptions_like_production', handle_exceptions_like_production: true do
before do |example|
case example.metadata[:type]
when :feature
method = Rails.application.method(:env_config)
allow(Rails.application).to receive(:env_config).with(no_args) do
method.call.merge(
'action_dispatch.show_exceptions' => true,
'action_dispatch.show_detailed_exceptions' => false,
'consider_all_requests_local' => true
)
end
when :controller
# In controller tests, we can only test *controller* behavior, not middleware behavior. We
# can disable show_detailed_exceptions here but we can *only* test any behaviors that depend
# on it that are defined in our *controller* (ApplicationController). Because the request
# doesn't go through the middleware (DebugExceptions, ShowExceptions) — which is what actually
# renders the production error pages — in controller tests, we may not see the exact same
# behavior as we would in production. Feature (end-to-end) tests may be needed to more
# accurately simulate a full production stack with middlewares.
request.set_header 'action_dispatch.show_detailed_exceptions', false
else
raise "expected example.metadata[:type] to be one of :feature or :controller but was #{example.metadata[:type]}"
end
end
end
RSpec.configure do |config|
config.include_context 'handle_exceptions_like_production', :handle_exceptions_like_production
end
然后,在端到端(功能)测试中,您希望它像在生产中一样处理异常(换句话说,不要将其视为本地请求),只需将:handle_exceptions_like_production
添加到示例组中:
描述“某物”:像处理生产一样处理异常
它…
终止
例如:
spec/features/exception\u handling\u spec.rb
:
shared_context 'handle_exceptions_like_production', handle_exceptions_like_production: true do
before do |example|
case example.metadata[:type]
when :feature
method = Rails.application.method(:env_config)
allow(Rails.application).to receive(:env_config).with(no_args) do
method.call.merge(
'action_dispatch.show_exceptions' => true,
'action_dispatch.show_detailed_exceptions' => false,
'consider_all_requests_local' => true
)
end
when :controller
# In controller tests, we can only test *controller* behavior, not middleware behavior. We
# can disable show_detailed_exceptions here but we can *only* test any behaviors that depend
# on it that are defined in our *controller* (ApplicationController). Because the request
# doesn't go through the middleware (DebugExceptions, ShowExceptions) — which is what actually
# renders the production error pages — in controller tests, we may not see the exact same
# behavior as we would in production. Feature (end-to-end) tests may be needed to more
# accurately simulate a full production stack with middlewares.
request.set_header 'action_dispatch.show_detailed_exceptions', false
else
raise "expected example.metadata[:type] to be one of :feature or :controller but was #{example.metadata[:type]}"
end
end
end
RSpec.configure do |config|
config.include_context 'handle_exceptions_like_production', :handle_exceptions_like_production
end
描述“异常处理”,js:false do
上下文“默认行为”是什么
这是一个很好的例子|
expect(例如,metadata[:handle_exceptions_like_production])等于nil
终止
请描述“ActiveRecord::RecordNotFound”的做法
是的
期待{
访问“/users/0”
}。引发_异常(ActiveRecord::RecordNotFound)
终止
终止
描述“ActionController::RoutingError”所做的工作
是的
期待{
维西