Created
November 7, 2012 08:50
-
-
Save xirukitepe/4030270 to your computer and use it in GitHub Desktop.
my personal reviewer about rspec basics!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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