Skip to content

Instantly share code, notes, and snippets.

@xirukitepe
Created November 7, 2012 08:50
Show Gist options
  • Save xirukitepe/4030270 to your computer and use it in GitHub Desktop.
Save xirukitepe/4030270 to your computer and use it in GitHub Desktop.
my personal reviewer about rspec basics!
#RSpec gives you a way to encapsulate what you’re testing via the describe block, and it’s friend context.
#In a general unit testing sense, we use describe to describe the behavior of a class:
describe Hash do
end
#Tests are written using the it block. Here’s an example of how you might write a spec for the Hash class:
describe Hash do
it "should return a blank instance" do
Hash.new.should == {}
end
end
#Don't forget to install rspec using
gem install rspec
#You can set up test state using the before and after directives. This will apply to anything in your describe block:
describe Hash do
before do
@hash = Hash.new({:hello => 'world'})
end
it "should return a blank instance" do
Hash.new.should == {}
end
it "hash the correct information in a key" do
@hash[:hello].should == 'world'
end
end
#Differences between :all and :each
#with :all -> the setup will be done once before all of the tests in the block
#with :each -> will be done before each individual test
#Using a “.” will signify that you’re testing a class method, and using “#” will signify that it’s an instance method.
#For example:
describe MyClass do
describe ".class_method_1" do
end
describe "#instance_method_1" do
end
end
#Essence of using context block
#The context method does the same thing by letting you contextualize a block of your tests. This is extremely powerful for test states when #you add more complicated setup and teardown code to really get in to your objects. I’ll show you a bit more of a real life scenario by #building a delicious burger class.
#Example:
describe Burger do
describe "#apply_ketchup" do
context "with ketchup" do
before do
@burger = Burger.new(:ketchup => true)
@burger.apply_ketchup
end
it "sets the ketchup flag to true" do
@burger.has_ketchup_on_it?.should be_true
end
end
context "without ketchup" do
before do
@burger = Burger.new(:ketchup => false)
@burger.apply_ketchup
end
it "sets the ketchup flag to false" do
@burger.has_ketchup_on_it?.should be_false
end
end
end
end
#before executing it, a burger should be created
@burger = Burger.new(:ketchup => true)
#And then implement the apply ketchup method
#If there's a ketchup then it should be true
#If there's no ketchup then it should be false
#And then apply a ketchup on it
#To summarize the code, there's another way:
describe Burger do
describe "#apply_ketchup" do
context "with ketchup" do
let(:burger) { Burger.new(:ketchup => true) }
before { burger.apply_ketchup }
it "sets the ketchup flag to true" do
burger.has_ketchup_on_it?.should be_true
end
end
context "without ketchup" do
let(:burger) { Burger.new(:ketchup => false) }
before { burger.apply_ketchup }
it "sets the ketchup flag to false" do
burger.has_ketchup_on_it?.should be_false
end
end
end
end
#This all works but we can clean it up even further using the subject method. The subject method tells rspec what we’re doing the tests on. #We’re going to combine that with the specify method in the next example. The specify method is just like the it method except the specify #method takes the code block as the description of the test:
describe Burger do
describe "#apply_ketchup" do
subject { burger }
before { burger.apply_ketchup }
context "with ketchup" do
let(:burger) { Burger.new(:ketchup => true) }
specify { subject.has_ketchup_on_it?.should be_true }
end
context "without ketchup" do
let(:burger) { Burger.new(:ketchup => true) }
specify { subject.has_ketchup_on_it?.should be_false }
end
end
end
#One neat thing about rspec is that the built in matchers will let you declaratively specify methods in your tests if they conform to a #certain naming convention. RSpec will look for methods that are named with has and end in a question mark to let you do write declarative #test code. Here’s what our final Burger class will look like using that idiom. Put the following in a file called burger_spec.rb and run it:
class Burger
attr_reader :options
def initialize(options={})
@options = options
end
def apply_ketchup
@ketchup = @options[:ketchup]
end
def has_ketchup_on_it?
@ketchup
end
end
describe Burger do
describe "#apply_ketchup" do
subject { burger }
before { burger.apply_ketchup }
context "with ketchup" do
let(:burger) { Burger.new(:ketchup => true) }
it { should have_ketchup_on_it }
end
context "without ketchup" do
let(:burger) { Burger.new(:ketchup => false) }
it { should_not have_ketchup_on_it }
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment