Skip to content

Instantly share code, notes, and snippets.

@jnstq
Created May 26, 2009 14:58
Show Gist options
  • Save jnstq/118102 to your computer and use it in GitHub Desktop.
Save jnstq/118102 to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'activerecord'
require 'activesupport'
require "spec/autorun"
require "spec/mocks"
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
ActiveRecord::Migration.verbose = false
ActiveRecord::Migration.suppress_messages do
ActiveRecord::Schema.define(:version => 0) do
create_table :users, :force => true do |t|
t.string :email, :password
end
end
end
class MethodRecorder < BlankSlate
attr_reader :recorded_method_calls
def initialize
@recorded_method_calls = []
end
def method_missing(name, *args)
recorder = MethodRecorder.new
@recorded_method_calls << [name, args, recorder]
recorder
end
end
class MethodRecorderPlayback
def initialize(target, recorded_method_calls)
puts "#{target}"
@target, @recorded_method_calls = target, recorded_method_calls
end
def playback
call_recoreded_methods(@target, @recorded_method_calls)
end
private
def call_recoreded_methods(target, recorded_method_calls)
recorded_method_calls.each do |name, args, chained|
call_recoreded_methods(target.send(name, *args), chained.recorded_method_calls)
end
end
end
module AnyInstance
METHOD_RECODING = {}
def new(*args, &blk)
super.tap do |instance|
MethodRecorderPlayback.new(instance, any_instance.recorded_method_calls).playback
end
end
def any_instance
METHOD_RECODING[self.class] ||= MethodRecorder.new
end
end
class User < ActiveRecord::Base
extend AnyInstance
end
# puts User.new.inspect
# User.any_instance.should_receive(:find).with(1)
# User.any_instance.should_receive(:destroy)
# puts User.any_instance.recorded_method_calls.inspect
#
# u = User.new
#
# p = MethodRecorderPlayback.new(u, User.any_instance.recorded_method_calls)
# p.playback
require 'spec/adapters/mock_frameworks/rspec'
module Spec
module Adapters
module MockFramework
def teardown_mocks_for_rspec_with_any_instance
teardown_mocks_for_rspec_without_any_instance
AnyInstance::METHOD_RECODING.clear
end
alias_method_chain :teardown_mocks_for_rspec, :any_instance
end
end
end
describe User do
before do
User.any_instance.stub!(:username).and_return('Bob')
User.any_instance.stub!(:password).and_return('hemligt')
end
it "should have a user name" do
User.new.username.should eql('Bob')
end
it "should have a user name" do
User.any_instance.should_receive(:password).and_return('hemligt')
User.new.password.should eql('hemligt')
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment