RSpec: TypeError при заполнении пользовательского исключения - PullRequest
0 голосов
/ 15 января 2019

Я хотел бы проверить, что 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 ]

0 голосов
/ 15 января 2019

Я полагаю, что вы правильно поняли, что проблема заключается в исключении против двойника. В частности, ошибка received :error with unexpected arguments, и сравнение состоит в том, что double не соответствует 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
0 голосов
/ 15 января 2019

Я полагаю, что экземпляр double Custom::Error является объектом InstanceDouble, а не объектом Exception, поэтому при поднятии double это вызывает TypeError.

Вы можете заменить двойной

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

с реальным Custom::Error объектом

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

чтобы избежать этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...