我想测试Custom::Runner.run
是否营救了所有StandardErrors
并发出异常警报。
我在弄清楚如何对自定义错误类Custom::Error
的调用进行存根时遇到了一些麻烦,并期望收到Custom::Alert.error
并以double作为参数。
下面是一个完整的测试案例来演示该问题:
module Custom
class Error < StandardError
end
end
module Custom
class Alert
def self.error(exception, context = {})
end
end
end
module Custom
class Runner
def self.run
request
rescue => e
Custom::Alert.error(e, { foo: :bar })
end
class << self
def request
raise Custom::Error.new('test')
end
end
end
end
这是测试:
RSpec.describe Custom::Runner do
describe '.run' do
let(:custom_error_double) { instance_double(Custom::Error) }
before do
# could this be the culprit?
allow(Custom::Error).to receive(:new)
.with('test')
.and_return(custom_error_double, 'test')
end
it 'fires a custom alert' do
expect(Custom::Alert).to receive(:error)
.with(custom_error_double, foo: :bar)
described_class.run
end
end
end
测试失败:
Failures:
1) Custom::Runner.run fires a custom alert
Failure/Error: Custom::Alert.error(e, { foo: :bar })
#<Custom::Alert (class)> received :error with unexpected arguments
expected: (#<InstanceDouble(Custom::Error) (anonymous)>, {:foo=>:bar})
got: (#<TypeError: exception class/object expected>, {:foo=>:bar})
Diff:
@@ -1,2 +1,2 @@
-[#<InstanceDouble(Custom::Error) (anonymous)>, {:foo=>:bar}]
+[#<TypeError: exception class/object expected>, {:foo=>:bar}]
我相信这是因为rescue
需要一个例外,并且我要返回一个double。我已经尝试过提高.and_raise(custom_error_double)
,但是我仍然得到相同的TypeError: exception class/object expected
。
这里一定有我想念的东西。任何建议将不胜感激。
答案 0 :(得分:1)
我猜想Custom::Error
的实例双精度对象是InstanceDouble
对象,而不是Exception
对象,因此当您提高双精度值时会导致TypeError
。
您可以替换双线
let(:custom_error_double) { instance_double(Custom::Error) }
带有真实的Custom::Error
对象
let(:custom_error) { Custom::Error.new }
避免这种情况。
答案 1 :(得分:0)
我相信您是完全正确的,例外与双重是问题所在。该错误具体是received :error with unexpected arguments
,并且比较是双精度数与TypeError
不匹配。在这种情况下,盲人rescue => e
然后调用Custom::Alert.error(e, {foo: :bar})
(以TypeError
作为参数e
),但是在测试中,.with()
期望
这将起作用:
RSpec.describe Custom::Runner do
describe '.run' do
let(:custom_error) { Custom::Error.new }
before do
allow(Custom::Error).to receive(:new).with('test').and_return(custom_error, 'test')
end
it 'fires a custom alert' do
expect(Custom::Alert).to receive(:error).with(custom_error, foo: :bar)
described_class.run
end
end
end