在调试失败的集成测试时,我总是遇到相同的问题,代码中引发的异常被抑制,并且没有显示在测试输出中。
例如,对于以下控制器和测试:
class RegistrationController::ApplicationController
def create
# some code that raises an exception
end
endclass RegistrationFlowTest < ActionDispatch::IntegrationTest
test 'user registers successfully' do
post sign_up_path, params: { username: 'arnold', password: '123' }
assert_response :success
end
end输出结果类似于
Minitest::Assertion: Expected response to be a <2XX: success>, but was a <500: Internal Server Error>有没有办法查看引发异常的确切原因?而不仅仅是HTTP响应代码的差异?
谢谢!
西蒙
发布于 2018-03-17 00:33:21
对于这个问题,我推荐的方法是实际解析Rails提供的响应(至少在test和development环境中是默认的),其中包括错误的堆栈跟踪,并在测试失败时进行处理。这样做的好处是,当出现不会导致测试失败的错误时,它不会输出堆栈跟踪(例如,您有意测试如何处理失败的场景)。
我制作的这个小模块将允许您调用assert_response_with_errors来断言对调用的响应,但当响应不是您所期望的时,以可读的格式输出异常消息和堆栈跟踪。
module ActionDispatch
module Assertions
module CustomResponseAssertions
# Use this method when you want to assert a response body but also print the exception
# and full stack trace to the test console.
# Useful when you are getting errors in integration tests but don't know what they are.
#
# Example:
# user_session.post create_gene_path, params: {...}
# user_session.assert_response_with_errors :created
def assert_response_with_errors(type, message = nil)
assert_response(type, message)
rescue Minitest::Assertion => e
message = e.message
message += "\nException message: #{@response.parsed_body[:exception]}"
stack_trace = @response.parsed_body[:traces][:'Application Trace'].map { |line| line[:trace] }.join "\n"
message += "\nException stack trace start"
message += "\n#{stack_trace}"
message += "\nException stack trace end"
raise Minitest::Assertion, message
end
end
end
end要使用它,您需要在Rails将其堆栈加载到test_helper.rb中之前将其包含在ActionDispatch::Assertions中。因此,只需将include预先添加到test_helper.rb中,如下所示:
ActionDispatch::Assertions.include ActionDispatch::Assertions::CustomResponseAssertions
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
...发布于 2018-02-14 23:29:22
这是因为Rails控制器默认情况下会处理异常并引发500状态,使异常对测试套件不可见(如果在模型的单元测试中引发错误,这将非常有用)。在您的测试套件中禁用此功能的选项或替代解决方法将在here中讨论。
该链接中的关键代码行,应该添加到test/integration/integration_test_helper.rb中
ActionController::Base.class_eval do
def perform_action
perform_action_without_rescue
end
end
Dispatcher.class_eval do
def self.failsafe_response(output, status, exception = nil)
raise exception
end
end编辑:我注意到这个链接现在已经很旧了。我真的很熟悉Rack,所以虽然第一个模块对我来说还可以,但我不确定第二个模块是否还会是当前版本。如果the relevant current Rails guide需要更新,你可能需要看看它。
https://stackoverflow.com/questions/48788810
复制相似问题