Class: Object

Inherits:
BasicObject
Defined in:
lib/stump/metaid.rb,
lib/stump/mock.rb,
lib/stump/stub.rb,
lib/stump/proxy.rb

Overview

Instance Method Summary collapse

Instance Method Details

#class_def(name, &blk) ⇒ Object

Defines an instance method within a class



14
15
16
# File 'lib/stump/metaid.rb', line 14

def class_def name, &blk
  class_eval { define_method name, &blk }
end

#meta_def(name, &blk) ⇒ Object

Adds methods to a metaclass



9
10
11
# File 'lib/stump/metaid.rb', line 9

def meta_def name, &blk
  meta_eval { define_method name, &blk }
end

#meta_eval(&blk) ⇒ Object



6
# File 'lib/stump/metaid.rb', line 6

def meta_eval &blk; metaclass.instance_eval &blk; end

#metaclassObject

The hidden singleton lurks behind everyone



5
# File 'lib/stump/metaid.rb', line 5

def metaclass; class << self; self; end; end

#mock!(method, options = {}, &block) ⇒ Object

Create a mock method on an object. A mock object will place an expectation on behavior and cause a test failure if it’s not fulfilled.

Examples

my_string = "a wooden rabbit"
my_string.mock!(:retreat!, :return => "run away!  run away!")
my_string.mock!(:question, :return => "what is the airspeed velocity of an unladen sparrow?")

# test/your_test.rb
my_string.retreat!    # => "run away!  run away!"
# If we let the test case end at this point, it fails with:
# Unmet expectation: #<Sparrow:1ee7> expected question


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/stump/mock.rb', line 16

def mock!(method, options = {}, &block)    
  Stump::Mocks.add([self, method])
  
  behavior =  if block_given?
                lambda do |*args| 
                  raise ArgumentError if block.arity >= 0 && args.length != block.arity
                  
                  Stump::Mocks.verify([self, method])
                  block.call(args)
                end
              else
                lambda do |*args|                     
                  Stump::Mocks.verify([self, method])
                  return options[:return]
                end
              end

  meta_def method, &behavior
end

#proxy!(method, options = {}, &block) ⇒ Object

Creates a proxy method on an object. In this setup, it places an expectation on an object (like a mock) but still calls the original method. So if you want to make sure the method is called and still return its value, or simply want to invoke the side effects of a method and return a stubbed value, then you can do that.

Examples

class Parrot
  def speak!
    puts @words
  end

  def say_this(words)
    @words = words
    "I shall say #{words}!"
  end
end

# => test/your_test.rb
sqawky = Parrot.new
sqawky.proxy!(:say_this)
# Proxy method still calls original method...
sqawky.say_this("hey")   # => "I shall say hey!"
sqawky.speak!            # => "hey"

sqawky.proxy!(:say_this, "herro!")
# Even though we return a stubbed value...
sqawky.say_this("these words")   # => "herro!"
# ...the side effects are still there.
sqawky.speak!                    # => "these words"

TODO: This implementation is still very rough. Needs refactoring and refining. Won’t work on ActiveRecord attributes, for example.



36
37
38
39
40
41
42
43
44
# File 'lib/stump/proxy.rb', line 36

def proxy!(method, options = {}, &block)
  Stump::Mocks.add([self, method])
  
  if respond_to?(method)
    proxy_existing_method(method, options, &block)
  else
    proxy_missing_method(method, options, &block)
  end
end

#stub!(method, options = {}, &block) ⇒ Object

Create a stub method on an object. Simply returns a value for a method call on an object.

Examples

my_string = "a wooden rabbit"
my_string.stub!(:retreat!, :return => "run away!  run away!")

# test/your_test.rb
my_string.retreat!    # => "run away!  run away!"


13
14
15
16
17
# File 'lib/stump/stub.rb', line 13

def stub!(method, options = {}, &block)
  behavior = (block_given? ? block : proc { return options[:return] })

  meta_def method, &behavior
end