如何在 rspec 中测试 rescue 子句中的代码
How to test code in rescue clause in rspec
我的代码中有以下模式:
重点是我们需要静默记录错误,但如果代码中有错误,测试需要失败。
begin
self.a_method_call
some_other_object.a_method_that_has_been_refactored
rescue StandardError => e
Rails.logger.error e.backtrace
end
如果由于 self.a_method_call
和 some_other_object.a_method_that_has_been_refactored
之间的交互而引发错误,则救援标准错误将消除任何错误并通过任何测试代码块的测试。如果 begin 子句中的代码有错误,我如何才能停止救援以便测试失败?
错误记录是其功能的一部分。不要让救援沉默,而是捕获错误日志记录。
正如所写,你可以通过 mocking the logger. Use with
to configure what arguments you expect Rails.logger.error
to receive. Since you don't know exactly what will be received, you can use various matchers like instance_of
来检查你得到了什么 backtrace
returns,一个数组。
it 'logs the backtrace as an error' do
# This comes before you call the method to set up the mock which expects
# to be called.
expect(Rails.logger).to receive(:error)
.with(instance_of(Array))
thing.some_method
end
因为这会替换 Rails.logger
,如果 thing.some_method
调用 Rails.logger
的过程中有任何其他内容,测试将失败。
我们可以通过小的重构使这更容易。不要直接使用 Rails.logger
,而是将其设为属性。
class SomeClass
attr_accessor :logger
def initialize
@logger = Rails.logger
end
def some_method
a_method_call
some_other_object.a_method_that_has_been_refactored
rescue StandardError => e
logger.error e.backtrace
end
end
现在我们可以专门模拟从 thing.logger
返回的内容。
it 'logs the backtrace as an error' do
# This comes before you call the method to set up the mock which expects
# to be called.
expect(thing.logger).to receive(:error)
.with(instance_of(Array))
thing.some_method
end
我的代码中有以下模式:
重点是我们需要静默记录错误,但如果代码中有错误,测试需要失败。
begin
self.a_method_call
some_other_object.a_method_that_has_been_refactored
rescue StandardError => e
Rails.logger.error e.backtrace
end
如果由于 self.a_method_call
和 some_other_object.a_method_that_has_been_refactored
之间的交互而引发错误,则救援标准错误将消除任何错误并通过任何测试代码块的测试。如果 begin 子句中的代码有错误,我如何才能停止救援以便测试失败?
错误记录是其功能的一部分。不要让救援沉默,而是捕获错误日志记录。
正如所写,你可以通过 mocking the logger. Use with
to configure what arguments you expect Rails.logger.error
to receive. Since you don't know exactly what will be received, you can use various matchers like instance_of
来检查你得到了什么 backtrace
returns,一个数组。
it 'logs the backtrace as an error' do
# This comes before you call the method to set up the mock which expects
# to be called.
expect(Rails.logger).to receive(:error)
.with(instance_of(Array))
thing.some_method
end
因为这会替换 Rails.logger
,如果 thing.some_method
调用 Rails.logger
的过程中有任何其他内容,测试将失败。
我们可以通过小的重构使这更容易。不要直接使用 Rails.logger
,而是将其设为属性。
class SomeClass
attr_accessor :logger
def initialize
@logger = Rails.logger
end
def some_method
a_method_call
some_other_object.a_method_that_has_been_refactored
rescue StandardError => e
logger.error e.backtrace
end
end
现在我们可以专门模拟从 thing.logger
返回的内容。
it 'logs the backtrace as an error' do
# This comes before you call the method to set up the mock which expects
# to be called.
expect(thing.logger).to receive(:error)
.with(instance_of(Array))
thing.some_method
end