require 'rails_helper'
RSpec.describe SportsService do
let(:user) { create(:user)}
describe '#call' do
it 'raises an error if the request is failed' do
service = described_class.new(user: user)
allow(service).to receive(:execute_request).with(anything).and_return(failed_response)
expect { service.call }.to raise_error ExceptionHandler::AuthenticationError
end
it 'send successful response' do
service = described_class.new(user: user)
allow(service).to receive(:execute_request).with(anything).and_return(successful_response)
sports_values_to_check = service.call.map {|sport| {id: sport.id, label: sport.label}}
expect(sports_values_to_check).to include(id: 1, label: 'sport-1')
end
end
end
def failed_response
double(:response, code: 100)
end
def successful_response
double(:response, code: 200, body: '[{"sport_id": 1, "label": "sport-1"}, {"sport_id": 2, "label": "sport-2"}]')
end1) SportsService#call send successful response
Failure/Error: create_sports(response.body)
#<Double :response> received unexpected message :body with (no args)
# ./app/services/sports_service.rb:17:in `call'
# ./spec/services/sports_service_spec.rb:17:in `block (3 levels) in <main>'
class ServiceProvider
@services = {}
def self.register(key, klass)
return false if @services.key?(key) && !Rails.env.test?
@services[key] = klass
end
def self.get(key)
@services[key]
end
def self.[](key)
get(key)
end
def self.finished_loading
@services.freeze unless Rails.env.test?
end
end
... #other services being declared here as well
ServiceProvider.register :sports_service, SportsService
ServiceProvider.finished_loadingmodule V1
class SportsController < ApplicationController
def index
json_response sports_service.call
end
private
def sports_service_class
@sports_service_class ||= ServiceProvider.get(:sports_service)
end
def sports_service
@sports_service ||= sports_service_class.new(user: current_user)
end
end
end
require 'rails_helper'
SuccessfulUserInfoService = Struct.new(:user, keyword_init: true) do
include ServiceClient
def call
true
end
end
RSpec.describe SportsService do
let(:user) { create(:user)}
describe '#call' do
after(:each) do
ServiceProvider.register(:sports_service, SportsService) # putting back the original service
end
...it 'sends a successful response with sports data' do
ServiceProvider.register(:sports_service, SuccessfulSportsService)
service = ServiceProvider.get(:sports_service)
allow(service).to receive(:execute_request).with(anything).and_return(successful_response)
service_data = service.call
sports_values_to_check = service_data.map {|sport| {id: sport.id, label: sport.label}}Its looks like your doubles are some how leaking between examples, I’d wager its something to do with your service injector but I’m unsure without a proper example.CheersJon Rowe
On Tuesday, 23 October 2018 21:52:38 UTC+2, Jon Rowe wrote:Its looks like your doubles are some how leaking between examples, I’d wager its something to do with your service injector but I’m unsure without a proper example.CheersJon RoweI think the problem comes from #successful_response method, - I checked and discovered that I had 2 ones in different specs, both are declared outside of main RSpec.describe block like that:#spec_one_spec.rbRSpec.describe 'SpecOne' do...# some examplesenddef successful_responsedouble(:response, code: 200)end#spec_two_spec.rbRSpec.describe 'SpecTwo' do...# some examplesenddef successful_responsedouble(:response, code: 200, body: '[{"sport_id": 1, "label": "sport-1"}, {"sport_id": 2, "label": "sport-2"}]')endWhat is the rule of thumb to declare such a kind of helper methods ? Should we put them inside the main RSpec.describe block, outside, make them private ?Cheers
def sandwich
Sandwich.new('delicious', [])
end