Skip to content

Instantly share code, notes, and snippets.

@dchelimsky
Forked from ryanb/1_let.rb
Created March 29, 2012 23:33
Show Gist options
  • Save dchelimsky/2244919 to your computer and use it in GitHub Desktop.
Save dchelimsky/2244919 to your computer and use it in GitHub Desktop.
let vs def
desc "A user's comment" do
let(:user) { User.create! name: "John" }
let(:comment) { user.comments.create! }
it "delegates to user's name" do
comment.name.should eq(user.name)
end
end
desc "A user's comment" do
def user
@user ||= User.create! name: "John"
end
def comment
@comment ||= user.comments.create!
end
it "delegates to user's name" do
comment.name.should eq(user.name)
end
end
desc "A user's comment" do
def user; @user ||= User.create! name: "John"; end
def comment; @comment ||= user.comments.create!; end
it "delegates to user's name" do
comment.name.should eq(user.name)
end
end
# the original motivation for `let` was to make this scenario easier:
# step 1
describe Thing do
it "does something" do
thing = Thing.new
thing.should do_something
end
end
# step 2 - add another example
describe Thing do
it "does something" do
thing = Thing.new
thing.should do_something
end
it "does something else" do
thing = Thing.new
thing.should do_something_else
end
end
# step 3 - refactor - without let
# 3a1
describe Thing do
before do
@thing = Thing.new
end
it "does something" do
thing = Thing.new
thing.should do_something
end
it "does something else" do
thing = Thing.new
thing.should do_something_else
end
end
# 3a2
describe Thing do
before do
@thing = Thing.new
end
it "does something" do
thing.should do_something
end
it "does something else" do
thing = Thing.new
thing.should do_something_else
end
end
# 3a3
describe Thing do
before do
@thing = Thing.new
end
it "does something" do
@thing.should do_something
end
it "does something else" do
thing = Thing.new
thing.should do_something_else
end
end
# 3a4
describe Thing do
before do
@thing = Thing.new
end
it "does something" do
@thing.should do_something
end
it "does something else" do
thing.should do_something_else
end
end
# 3a5
describe Thing do
before do
@thing = Thing.new
end
it "does something" do
@thing.should do_something
end
it "does something else" do
@thing.should do_something_else
end
end
# and now with let - fewer steps, no adding @ signs
# 3b1
describe Thing do
let(:thing) { Thing.new }
it "does something" do
thing = Thing.new
thing.should do_something
end
it "does something else" do
thing = Thing.new
thing.should do_something_else
end
end
# 3b2
describe Thing do
let(:thing) { Thing.new }
it "does something" do
thing.should do_something
end
it "does something else" do
thing = Thing.new
thing.should do_something_else
end
end
# 3b2
describe Thing do
let(:thing) { Thing.new }
it "does something" do
thing.should do_something
end
it "does something else" do
thing.should do_something_else
end
end
@croaky
Copy link

croaky commented Apr 16, 2012

I find 3a5 the most readable and consistent with the Four-Phase Test. Not sure I understand the gains of the memoization and agree with @tenderlove that the hidden conditional is a little freaky.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment