Module: RSpec::Core::Let::ExampleGroupMethods

Included in:
SharedContext
Defined in:
lib/rspec/core/let.rb

Instance Method Summary collapse

Instance Method Details

#let(name, &block) ⇒ Object

Generates a method whose return value is memoized after the first call.

Examples:


describe Thing do
  let(:thing) { Thing.new }

  it "does something" do
    # first invocation, executes block, memoizes and returns result
    thing.do_something

    # second invocation, returns the memoized value
    thing.should be_something
  end
end

22
23
24
25
26
# File 'lib/rspec/core/let.rb', line 22

def let(name, &block)
  define_method(name) do
    __memoized.fetch(name) {|k| __memoized[k] = instance_eval(&block) }
  end
end

#let!(name, &block) ⇒ Object

Just like let(), except the block is invoked by an implicit before hook. This serves a dual purpose of setting up state and providing a memoized reference to that state.

Examples:


class Thing
  def self.count
    @count ||= 0
  end

  def self.count=(val)
    @count += val
  end

  def self.reset_count
    @count = 0
  end

  def initialize
    self.class.count += 1
  end
end

describe Thing do
  after(:each) { Thing.reset_count }

  context "using let" do
    let(:thing) { Thing.new }

    it "is not invoked implicitly" do
      Thing.count.should eq(0)
    end

    it "can be invoked explicitly" do
      thing
      Thing.count.should eq(1)
    end
  end

  context "using let!" do
    let!(:thing) { Thing.new }

    it "is invoked implicitly" do
      Thing.count.should eq(1)
    end

    it "returns memoized version on first invocation" do
      thing
      Thing.count.should eq(1)
    end
  end
end

82
83
84
85
# File 'lib/rspec/core/let.rb', line 82

def let!(name, &block)
  let(name, &block)
  before { __send__(name) }
end