【问题标题】:How do I stub exception with error in RSpec?如何在 RSpec 中存根异常并出现错误?
【发布时间】:2019-11-07 14:37:04
【问题描述】:

当它进入异常部分以遵循“.get”方法时,我不确定如何处理测试:

/api/reddit_client.rb

module Api
    class RedditClient

      def self.get(path, access_token)
        begin
          response = RestClient.get(
            path,
            { :Authorization => "Bearer #{access_token}" }
          )

          json_parse(response)
        rescue RestClient::ExceptionWithResponse => e
          logger.error "%%% Something went wrong in request post"
          logger.error "%%% It fails with error: #{e.http_code}"
          logger.error "%%% And with message: #{e.message}"

          { "message" => e.message, "error" => e.http_code }
        end
      end

      ...
      ...
      ...

        private

        def json_parse(response)
          JSON.parse(response.body)
        end
    end
end

我希望它测试它是否引发“RestClient::ExceptionWithResponse”,为此我做了以下操作:

/api/reddit_client_spec.rb

require 'rails_helper'

RSpec.describe Api::RedditClient do
    let(:path) { 'https://www.somerandomapi.com' }
    let(:access_token) { 'f00TOk3N' }

    describe '.get' do
      subject { described_class.get(path, access_token)}

      context 'when not authorized' do
        before do
          allow(described_class)
            .to receive(:get)
            .and_raise(RestClient::ExceptionWithResponse)
        end

        it 'returns hash with error infos' do
          expect{ subject }.to raise_error(RestClient::ExceptionWithResponse)
        end
      end
    end
end

欺骗我的是,我还想测试 Rails.logger.error 是否也被调用了 3 次,并检查我的哈希错误返回。如何测试这种情况?

【问题讨论】:

    标签: ruby-on-rails rspec stub


    【解决方案1】:

    您不能对Api::RedditClient.get 本身存根,因为这样您要测试的代码根本不会执行。

    取而代之的是存根RestClient.get,例如:

    allow(RestClient)
      .to receive(:get)
      .and_raise(RestClient::ExceptionWithResponse)
    

    关于断言,rspec 有办法检查给定方法是否已被调用 N 次:

    https://relishapp.com/rspec/rspec-mocks/v/3-5/docs/setting-constraints/receive-counts

    expect(Rails.logger).to receive(:error).exactly(3).times
    

    【讨论】:

      【解决方案2】:

      要检查是否使用不同的消息调用 Rails 记录器 3 次,您可以结合使用 receiveordered 方法。

      同时使用RestClient 代替Api::RedditClient 以执行方法并捕获异常。

      你的代码会是这样的:

       context 'when not authorized' do
         before do
           allow(RestClient) # <- Note that you should use RestClient instead of Api::RedditClient 
             .to receive(:get)
             .and_raise(RestClient::ExceptionWithResponse)
         end
      
         it 'should raise error' do
           expect(Rails.logger).to receive(:error).with("%%% Something went wrong in request post").ordered
           expect(Rails.logger).to receive(:error).with(""%%% It fails with error: 401"").ordered
           expect(Rails.logger).to receive(:error).with("%%% And with message: Exception Message").ordered
           
           expect{ subject }.to raise_error(RestClient::ExceptionWithResponse)
         end
       end
      

      要检查返回响应,您可以在测试中挽救异常并检查返回类型

      it 'returns hash with error infos' do
         expect{ subject rescue nil}.to include({ "message" => "Exception Message", "error" => 401 })
      end
      

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-11
        • 1970-01-01
        • 1970-01-01
        • 2021-03-15
        • 1970-01-01
        • 2013-02-03
        • 2023-03-03
        • 1970-01-01
        相关资源
        最近更新 更多