Skip to content

Instantly share code, notes, and snippets.

@dux
Last active August 12, 2017 15:32
Show Gist options
  • Save dux/07dea105b127a76043dd751146651822 to your computer and use it in GitHub Desktop.
Save dux/07dea105b127a76043dd751146651822 to your computer and use it in GitHub Desktop.
Simple mock - lightweight mocking, supports method mocks, sequences, traits
class SimpleMock
attr_reader :object
@@mock_data = {}
@@sequence ||= {}
class << self
def define name, &block
@@mock_data[name] = block
end
def build *args
object = new(*args).object
yield object if block_given?
object
end
def create *args
object = build *args
object.save
yield object if block_given?
object
end
end
###
def initialize *args
opts = args.last.is_a?(Hash) ? args.pop : {}
@klass = args.shift
@traits = args
block = @@mock_data[@klass] || raise('object not defined')
@object = @klass.to_s.classify.constantize.new
instance_exec @object, &block
raise 'Trait [%s] not found' % @traits.join(', ') if @traits.first
opts.each { |k,v| @object.send("#{k}=", v) }
end
def trait(name, &block)
if @traits.delete(name)
instance_exec(@object, &block)
end
end
def func(name, &block)
@object.define_singleton_method(name, &block)
end
def sequence(name, start=nil)
@@sequence[@klass] ||= {}
@@sequence[@klass][name] ||= start || 0
@@sequence[@klass][name] += 1
end
end
require './config/application'
require 'simple_mock'
require 'faker'
SimpleMock.define :user do |u|
u.name = 'User %s' % sequence(:foo)
u.email = Faker::Internet.email
func :test1 do
'foo bar custom: %s' % name
end
trait :bad_email do |o|
o.email = 'Dux'
end
trait :overload do |o|
func :name do
'OVERLOADED'
end
end
end
user1 = SimpleMock.create(:user)
user2 = SimpleMock.create(:user, :bad_email)
user3 = SimpleMock.create(:user, name: 'Foo Barr')
user4 = SimpleMock.create(:user, :overload)
p user1.name # "User 1"
p user2.name # "User 2"
p user3.name # "Foo Barr"
p user4.name # "OVERLOADED"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment