Created
November 27, 2013 07:38
-
-
Save sanandnarayan/7671990 to your computer and use it in GitHub Desktop.
Temporarily over-riding classes in ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Ever wondered, how RSpec does Stubbing. | |
# They use Ruby's metaprogamming abilities. | |
# Lets talk a closer look. | |
# Every class in ruby inherits from a special class | |
# named "Object" . | |
class Object | |
# We are adding a mock_methods function which will be available to every | |
# object. | |
def mock_methods(methods_to_mock) | |
# We are backing-up the caller of this method | |
original = self | |
# We are creating a new class which will have the mock methods | |
klass = Class.new(self) do | |
# We are defining the mocked methods on this new class | |
instance_eval do | |
methods_to_mock.each do |method, proc| | |
define_method(method, &proc) | |
end | |
end | |
end | |
begin | |
# Removing the original class | |
Object.send(:remove_const, self.name.to_s) | |
# Attaching the new class to the program | |
Object.const_set(self.name.intern, klass) | |
# Executing the block passed | |
yield | |
ensure | |
# We are brining the original class back. | |
Object.send(:remove_const, self.name.to_s) | |
Object.const_set(self.name.intern, original) | |
end | |
end | |
end | |
class Duck | |
def quak; puts "Quak"; end | |
end | |
Duck.new.quak #=> "Quak" | |
Duck.mock_methods(:quak => Proc.new { puts 'Wuff' }) do | |
Duck.new.quak #=> "Wuff" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment