代码之家  ›  专栏  ›  技术社区  ›  doremi

rspec:stubing自定义异常时出现类型错误

  •  1
  • doremi  · 技术社区  · 6 年前

    我想测试一下 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 需要例外,我将返回一个双精度值。我试着提高 .and_raise(custom_error_double) 但是我还是继续得到同样的结果 TypeError: exception class/object expected .

    这里一定有我找不到的东西。任何建议都将不胜感激。

    2 回复  |  直到 6 年前
        1
  •  0
  •   James Milani    6 年前

    我相信你完全正确地认为例外与双倍是问题所在。具体的错误是 received :error with unexpected arguments 与之相比,双精度数与 TypeError . 在这种情况下,盲人 rescue => e 然后调用 Custom::Alert.error(e, {foo: :bar}) (其中有 类型错误 作为论点 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
    
        2
  •  1
  •   periswon    6 年前

    我想这个例子是 Custom::Error 是一个 InstanceDouble 对象而不是 Exception 对象,因此当您提升双精度时,它会导致 TypeError .

    你可以换双的

     let(:custom_error_double) { instance_double(Custom::Error) }
    

    带着真实 自定义:错误 对象

     let(:custom_error) { Custom::Error.new }
    

    为了避免这种情况。