module MyApiClient::Stub
Test helper module for RSpec
Constants
- ERROR_MESSAGE
Public Instance Methods
Returns a stubbed arbitrary MyApiClient
instance.
@param klass [Class]
Stubbing target class.
@param actions_and_options [Hash]
Stubbing target method and options
@example
api_client = stub_api_client( ExampleApiClient, get_users: { # Returns an arbitrary pageable response pageable: [ { id: 1 }, { id: 2 }] # for `#pageable_get`. }, get_user: { response: { id: 1 } }, # Returns an arbitrary response. post_users: { id: 1 }, # You can ommit `response` keyword. patch_user: ->(params) { { id: params[:id] } }, # Returns calculated result as response. put_user: { raise: MyApiClient::ClientError } # Raises an arbitrary error. delete_user: { raise: MyApiClient::ClientError, response: { errors: [{ code: 10 }] }, # You can stub response and status code status_code: 403, # with exception. } ) response = api_client.get_user(id: 123) response.id # => 1
@return [InstanceDouble]
Returns a spy object of the stubbed ApiClient.
# File lib/my_api_client/rspec/stub.rb, line 70 def stub_api_client(klass, **actions_and_options) instance = instance_double(klass) actions_and_options.each { |action, options| stubbing(instance, action, options) } instance end
Stubs all instance of arbitrary MyApiClient
class. And returns a stubbed arbitrary MyApiClient
instance.
@param klass [Class]
Stubbing target class.
@param actions_and_options [Hash]
Stubbing target method and options
@example
stub_api_client_all( ExampleApiClient, get_users: { # Returns an arbitrary pageable response pageable: [ { id: 1 }, { id: 2 }] # for `#pageable_get`. }, get_user: { response: { id: 1 } }, # Returns an arbitrary response. post_users: { id: 1 }, # You can ommit `response` keyword. patch_user: ->(params) { { id: params[:id] } }, # Returns calculated result as response. put_user: { raise: MyApiClient::ClientError } # Raises an arbitrary error. delete_user: { raise: MyApiClient::ClientError, response: { errors: [{ code: 10 }] }, # You can stub response and statu code status_code: 429, # with an arbitrary error. } ) response = ExampleApiClient.new.get_user(id: 123) response.id # => 1
@return [InstanceDouble]
Returns a spy object of the stubbed ApiClient.
# File lib/my_api_client/rspec/stub.rb, line 38 def stub_api_client_all(klass, **actions_and_options) instance = stub_api_client(klass, **actions_and_options) allow(klass).to receive(:new).and_return(instance) instance end
Private Instance Methods
# File lib/my_api_client/rspec/stub.rb, line 160 def agent instance_double(Sawyer::Agent).tap do |agent| allow(agent).to receive(:parse_links) do |data| data ||= {} links = data.delete(:_links) [data, links] end end end
# File lib/my_api_client/rspec/stub.rb, line 84 def generate_stubbed_response(options, *request) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength case options when Proc stub_as_resource(options.call(*request)) when Hash if options[:raise] # rubocop:disable Style/GuardClause raise process_raise_option(options[:raise], options[:response], options[:status_code]) elsif options[:response] stub_as_resource(options[:response]) elsif options[:pageable].is_a?(Enumerable) stub_as_pageable_resource(options[:pageable].each, *request) else stub_as_resource(options) end else stub_as_resource(options) end end
Provides a shorthand for `raise` option. `MyApiClient::Error` requires `MyApiClient::Params::Params` instance on initialize, but it makes trubolesome. `MyApiClient::NetworkError` is more. If given a error instance, it will return raw value without processing.
@param exception [Clsas, MyApiClient::Error] Processing target. @param response [Hash] describe_response_here @param status_code [Integer] describe_status_code_here @return [MyApiClient::Error] Processed exception. @raise [RuntimeError] Unsupported error class was set.
# File lib/my_api_client/rspec/stub.rb, line 123 def process_raise_option(exception, response, status_code) case exception when Class params = MyApiClient::Params::Params.new(nil, stub_as_response(response, status_code)) if exception == MyApiClient::NetworkError exception.new(params, Net::OpenTimeout.new) else exception.new(params) end when MyApiClient::Error raise ERROR_MESSAGE if response.present? exception else raise "Unsupported error class was set: #{exception.inspect}" end end
# File lib/my_api_client/rspec/stub.rb, line 103 def stub_as_pageable_resource(pager, *request) Enumerator.new do |y| loop do y << generate_stubbed_response(pager.next, *request) rescue StopIteration break end end.lazy end
# File lib/my_api_client/rspec/stub.rb, line 151 def stub_as_resource(params) case params when Hash then Sawyer::Resource.new(agent, params) when Array then params.map { |hash| stub_as_resource(hash) } when nil then nil else params end end
# File lib/my_api_client/rspec/stub.rb, line 141 def stub_as_response(params, status_code) instance_double( Sawyer::Response, status: status_code.presence || 400, headers: {}, data: stub_as_resource(params), timing: 0.123 ) end
# File lib/my_api_client/rspec/stub.rb, line 78 def stubbing(instance, action, options) allow(instance).to receive(action) do |*request| generate_stubbed_response(options, *request) end end