Skip to content

Instantly share code, notes, and snippets.

@krzykamil
Created October 7, 2022 09:24
Show Gist options
  • Save krzykamil/1e05cadb0fdebde8b0ae6d772fead308 to your computer and use it in GitHub Desktop.
Save krzykamil/1e05cadb0fdebde8b0ae6d772fead308 to your computer and use it in GitHub Desktop.
RSpec DSL for stubbing services
module Support
module Services
class HaveBeenCalledMatcher
include RSpec::Mocks::Matchers::Matcher
NotCalledYet = Class.new(StandardError)
def initialize(&block)
@matcher = RSpec::Mocks::Matchers::HaveReceived.new(:call, &block)
end
def matches?(actual, &block)
until matcher.matches?(actual, &block)
started ||= Time.now
return false unless @eventually
return false unless Time.now - started < @eventually
sleep 0.1
end
true
end
def name
'have_been_called'
end
delegate :failure_message, :failure_message_when_negated, to: :matcher
def eventually(timeout = 5)
@eventually = timeout
self
end
private
attr_reader :matcher
def method_missing(name, *args, &block)
super unless matcher.respond_to?(name)
@matcher = matcher.__send__(name, *args, &block)
self
end
def respond_to_missing?(name, priv = false)
matcher.respond_to?(name, priv)
end
end
def be_called(&block)
receive(:call, &block)
end
def have_been_called(&block)
HaveBeenCalledMatcher.new(&block)
end
def stub_services(*args)
args.each do |klass|
stub_service klass
end
end
def spy_on_services(*args)
args.each do |klass|
spy_on_service klass
end
end
def stub_service(klass, return_value = nil)
allow(klass).to receive(:call).and_return return_value
end
def spy_on_service(klass)
allow(klass).to receive(:call).and_call_original
end
def unstub_services(*args)
args.each do |klass|
allow(klass).to receive(:call).and_call_original
end
end
RSpec.configure do |rspec|
rspec.include self
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment