SlideShare ist ein Scribd-Unternehmen logo
1 von 86
Rspec and Rails
    Abraham Kuri
Table of Contents
01   Rails setup
02   Expectations & Matchers
03   Shoulda & DRY Specs
04   Context & Describe blocks
05   Before block
06   Stub & Mock
07   Where to go next?
Rails Setup
Rails Setup
Rails Setup

$ rails new <app_name> --skip-test-unit
Rails Setup

$ rails new <app_name> --skip-test-unit

Gemfile:

group   :test, :development do
  gem   'rspec-rails'
  gem   "factory_girl_rails"
  gem   'ffaker'
end
Rails Setup

$ rails new <app_name> --skip-test-unit

Gemfile:

group   :test, :development do
  gem   'rspec-rails'
  gem   "factory_girl_rails"
  gem   'ffaker'
end
Rails Setup

$ rails new <app_name> --skip-test-unit

Gemfile:

group   :test, :development do
  gem   'rspec-rails'
  gem   "factory_girl_rails"
  gem   'ffaker'
end
Rails Setup

$ rails new <app_name> --skip-test-unit

Gemfile:

group   :test, :development do
  gem   'rspec-rails'
  gem   "factory_girl_rails"
  gem   'ffaker'
end




$ bundle install
Rails Setup

$ rails new <app_name> --skip-test-unit

Gemfile:

group   :test, :development do
  gem   'rspec-rails'
  gem   "factory_girl_rails"
  gem   'ffaker'
end




$ bundle install
$ rails g rspec:install
Expectations & Matchers
‣ user_spec.rb
Expectations & Matchers
‣ user_spec.rb
Expectations & Matchers
‣ user_spec.rb
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  it 'should not be valid without a name' do
    user.name = nil
    user.should_not == nil
  end
end
Expectations & Matchers
‣ user_spec.rb
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  it 'should not be valid without a name' do
    user.name = nil
    user.should_not == nil
  end
end
Expectations & Matchers
‣ user_spec.rb
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  it 'should not be valid without a name' do
    user.name = nil     modifier
    user.should_not == nil
  end
end
Expectations & Matchers
‣ user_spec.rb
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  it 'should not be valid without a name' do
    user.name = nil     modifier
    user.should_not == nil
  end
end
Expectations & Matchers
‣ user_spec.rb
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  it 'should not be valid without a name' do
    user.name = nil     modifier
    user.should_not == nil
  end
end                         matcher
Expectations & Matchers
‣ user_spec.rb
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  it 'should not be valid without a name' do
    user.name = nil     modifier
    user.should_not == nil
  end
end                         matcher
Expectations & Matchers
‣ user_spec.rb
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  it 'should not be valid without a name' do
    user.name = nil     modifier
    user.should_not == nil
  end
end                         matcher
Expectations & Matchers
‣ user_spec.rb
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  it 'should not be valid without a name' do
    user.name = nil     modifier
    user.should_not == nil
  end
end                         matcher
Expectations & Matchers
‣ user_spec.rb
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  it 'should not be valid without a name' do
    user.name = nil     modifier
    user.should_not == nil
  end
end                         matcher



 describe User do
   let(:user) { FactoryGirl.create(:user) }
   subject { user }

   its(:name) { should_not be_nil }
 end
Expectations & Matchers
‣ user_spec.rb
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  it 'should not be valid without a name' do
    user.name = nil     modifier
    user.should_not == nil
  end
end                         matcher



 describe User do
   let(:user) { FactoryGirl.create(:user) }
   subject { user }

   its(:name) { should_not be_nil }
 end
Other matchers
Other matchers
user.name.should == "Abraham"

user.friends.should > 3

user.alive.should == true


user.alive.should_not == false


user.girlfriend.should == nil


user.should be_alive

                                          have(n)
user.friends.should include(other_user)   have_at_least(n)
                                          have_at_most(n)
user.should have(2).arms
Other matchers
user.name.should == "Abraham"

user.friends.should > 3

user.alive.should == true
                                 user.alive.should be_true

user.alive.should_not == false


user.girlfriend.should == nil


user.should be_alive

                                               have(n)
user.friends.should include(other_user)        have_at_least(n)
                                               have_at_most(n)
user.should have(2).arms
Other matchers
user.name.should == "Abraham"

user.friends.should > 3

user.alive.should == true
                                 user.alive.should be_true

user.alive.should_not == false
                                 user.alive.should_not be_false

user.girlfriend.should == nil


user.should be_alive

                                               have(n)
user.friends.should include(other_user)        have_at_least(n)
                                               have_at_most(n)
user.should have(2).arms
Other matchers
user.name.should == "Abraham"

user.friends.should > 3

user.alive.should == true
                                 user.alive.should be_true

user.alive.should_not == false
                                 user.alive.should_not be_false

user.girlfriend.should == nil
                                 user.alive.should be_nil

user.should be_alive

                                               have(n)
user.friends.should include(other_user)        have_at_least(n)
                                               have_at_most(n)
user.should have(2).arms
Shoulda to the rescue
Shoulda to the rescue
Shoulda to the rescue
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  its(:name) { should_not be_nil }

end
Shoulda to the rescue
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  its(:name) { should_not be_nil }

end
Shoulda to the rescue
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  its(:name) { should_not be_nil }

end


it { should validate_presence_of(:name) }
Shoulda to the rescue
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  its(:name) { should_not be_nil }

end


it { should validate_presence_of(:name) }

it { should validate_uniqueness_of(:email) }

it { should have_many(:friends).through(:friendship) }
Shoulda to the rescue
describe User do
  let(:user) { FactoryGirl.create(:user) }
  subject { user }

  its(:name) { should_not be_nil }

end


it { should validate_presence_of(:name) }

it { should validate_uniqueness_of(:email) }

it { should have_many(:friends).through(:friendship) }


it { should belong_to(:user)}
Context & Describe Blocks
Context & Describe Blocks
describe User do
  describe 'when sleep' do
    it 'snores'
    describe 'with a soft pillow' do
      it 'still snores'
      it 'have good dreams'
    end
  end
end
Context & Describe Blocks
describe User do
  describe 'when sleep' do
    it 'snores'
    describe 'with a soft pillow' do
      it 'still snores'
      it 'have good dreams'
    end
  end
end
Context & Describe Blocks
describe User do
  describe 'when sleep' do
    it 'snores'
    describe 'with a soft pillow' do
      it 'still snores'
      it 'have good dreams'
    end
  end
end          Use context instead       of describe
Context & Describe Blocks
describe User do
  describe 'when sleep' do
    it 'snores'
    describe 'with a soft pillow' do
      it 'still snores'
      it 'have good dreams'
    end
  end
end          Use context instead       of describe


describe User do
  context 'when sleep' do
    it 'snores'
    context 'with a soft pillow' do
      it 'still snores'
      it 'have good dreams'
    end
  end
end
Context & Describe Blocks
describe User do
  describe 'when sleep' do
    it 'snores'
    describe 'with a soft pillow' do
      it 'still snores'
      it 'have good dreams'
    end
  end
end          Use context instead       of describe


describe User do
  context 'when sleep' do
    it 'snores'
    context 'with a soft pillow' do
      it 'still snores'
      it 'have good dreams'
    end
  end
end
Before block
Before block
describe 'friends names' do
  context 'when has friends' do
    it 'should have 3 friends' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.should have(3).friends
    end
    it 'should return friend names' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.friend_names.should == user.friends.map(&:name)
    end
  end
end
Before block
describe 'friends names' do
  context 'when has friends' do
    it 'should have 3 friends' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.should have(3).friends
    end
    it 'should return friend names' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.friend_names.should == user.friends.map(&:name)
    end
  end
end
Before block
describe 'friends names' do
  context 'when has friends' do
    it 'should have 3 friends' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.should have(3).friends
    end
    it 'should return friend names' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.friend_names.should == user.friends.map(&:name)
    end
  end
end                                         Let’s be more DRY
Before block
describe 'friends names' do
  context 'when has friends' do
    it 'should have 3 friends' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.should have(3).friends
    end
    it 'should return friend names' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.friend_names.should == user.friends.map(&:name)
    end
  end
end                                         Let’s be more DRY


describe 'friends names' do
Before block
describe 'friends names' do
  context 'when has friends' do
    it 'should have 3 friends' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.should have(3).friends
    end
    it 'should return friend names' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.friend_names.should == user.friends.map(&:name)
    end
  end
end                                         Let’s be more DRY


describe 'friends names' do
  context 'when has friends' do
Before block
describe 'friends names' do
  context 'when has friends' do
    it 'should have 3 friends' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.should have(3).friends
    end
    it 'should return friend names' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.friend_names.should == user.friends.map(&:name)
    end
  end
end                                         Let’s be more DRY


describe 'friends names' do
  context 'when has friends' do
    before do
Before block
describe 'friends names' do
  context 'when has friends' do
    it 'should have 3 friends' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.should have(3).friends
    end
    it 'should return friend names' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.friend_names.should == user.friends.map(&:name)
    end
  end
end                                         Let’s be more DRY


describe 'friends names' do
  context 'when has friends' do
    before do
      3.times { user.friends << FactoryGirl.create(:friend) }
Before block
describe 'friends names' do
  context 'when has friends' do
    it 'should have 3 friends' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.should have(3).friends
    end
    it 'should return friend names' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.friend_names.should == user.friends.map(&:name)
    end
  end
end                                         Let’s be more DRY


describe 'friends names' do
  context 'when has friends' do
    before do
      3.times { user.friends << FactoryGirl.create(:friend) }
    end
Before block
describe 'friends names' do
  context 'when has friends' do
    it 'should have 3 friends' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.should have(3).friends
    end
    it 'should return friend names' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.friend_names.should == user.friends.map(&:name)
    end
  end
end                                         Let’s be more DRY


describe 'friends names' do
  context 'when has friends' do
    before do
      3.times { user.friends << FactoryGirl.create(:friend) }
    end
    it { should have(3).friends }
Before block
describe 'friends names' do
  context 'when has friends' do
    it 'should have 3 friends' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.should have(3).friends
    end
    it 'should return friend names' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.friend_names.should == user.friends.map(&:name)
    end
  end
end                                         Let’s be more DRY


describe 'friends names' do
  context 'when has friends' do
    before do
      3.times { user.friends << FactoryGirl.create(:friend) }
    end
    it { should have(3).friends }
    its(:friend_names) { should == user.friends.map(&:name) }
Before block
describe 'friends names' do
  context 'when has friends' do
    it 'should have 3 friends' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.should have(3).friends
    end
    it 'should return friend names' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.friend_names.should == user.friends.map(&:name)
    end
  end
end                                         Let’s be more DRY


describe 'friends names' do
  context 'when has friends' do
    before do
      3.times { user.friends << FactoryGirl.create(:friend) }
    end
    it { should have(3).friends }
    its(:friend_names) { should == user.friends.map(&:name) }
  end
Before block
describe 'friends names' do
  context 'when has friends' do
    it 'should have 3 friends' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.should have(3).friends
    end
    it 'should return friend names' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.friend_names.should == user.friends.map(&:name)
    end
  end
end                                         Let’s be more DRY


describe 'friends names' do
  context 'when has friends' do
    before do
      3.times { user.friends << FactoryGirl.create(:friend) }
    end
    it { should have(3).friends }
    its(:friend_names) { should == user.friends.map(&:name) }
  end
end
Before block
describe 'friends names' do
  context 'when has friends' do
    it 'should have 3 friends' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.should have(3).friends
    end
    it 'should return friend names' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.friend_names.should == user.friends.map(&:name)
    end
  end
end                                         Let’s be more DRY


describe 'friends names' do
  context 'when has friends' do
    before do
      3.times { user.friends << FactoryGirl.create(:friend) }
    end
    it { should have(3).friends }
    its(:friend_names) { should == user.friends.map(&:name) }
  end
end
Before block
describe 'friends names' do
  context 'when has friends' do
    it 'should have 3 friends' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.should have(3).friends
    end
    it 'should return friend names' do
      3.times { user.friends << FactoryGirl.create(:friend) }
      user.friend_names.should == user.friends.map(&:name)
    end
  end
end                                         Let’s be more DRY


describe 'friends names' do
  context 'when has friends' do
    before do
      3.times { user.friends << FactoryGirl.create(:friend) }
    end
    it { should have(3).friends }
    its(:friend_names) { should == user.friends.map(&:name) }
  end
end                                           Much better
Stubs & Mocking
Stubs & Mocking
‣ Stubs

 For replacing a method with code that
 return a specified result
Stubs & Mocking
‣ Stubs

  For replacing a method with code that
  return a specified result



‣ Mocks

 A stub with an expectations that the
 method gets called
Stub it out
Stub it out



app/models/user.rb
class User < ActiveRecord::Base
  has_one :stomach

  def feed_stomach
    stomach.feed(self)
    self.status = "full"
  end

end
Stub it out
        User
      feed_stomach




app/models/user.rb
class User < ActiveRecord::Base
  has_one :stomach

  def feed_stomach
    stomach.feed(self)
    self.status = "full"
  end

end
Stub it out
        User
      feed_stomach




app/models/user.rb
class User < ActiveRecord::Base
  has_one :stomach

  def feed_stomach
    stomach.feed(self)
    self.status = "full"
  end

end
Stub it out
        User                          Stomach
      feed_stomach                def feed(*args)
                                    return nil
                                  end




app/models/user.rb
class User < ActiveRecord::Base
  has_one :stomach

  def feed_stomach
    stomach.feed(self)
    self.status = "full"
  end

end
Stub it out
        User                          Stomach
      feed_stomach                def feed(*args)
                                    return nil
                                  end


                                                    user.stomach.stub(:feed_stomach)



app/models/user.rb
class User < ActiveRecord::Base
  has_one :stomach

  def feed_stomach
    stomach.feed(self)
    self.status = "full"
  end

end
Complete spec
Complete spec
                def feed_stomach
                  stomach.feed(self)
                  self.status = "full"
                end
Complete spec
                                                  def feed_stomach
                                                    stomach.feed(self)
/spec/models/user_spec.rb                           self.status = "full"
                                                  end




                  We need to test that feed is called
Complete spec
                                                   def feed_stomach
                                                     stomach.feed(self)
/spec/models/user_spec.rb                            self.status = "full"
                                                   end
describe User do




                   We need to test that feed is called
Complete spec
                                                  def feed_stomach
                                                    stomach.feed(self)
/spec/models/user_spec.rb                           self.status = "full"
                                                  end
describe User do
  let(:user) { FactoryGirl.create(:user) }




                  We need to test that feed is called
Complete spec
                                                  def feed_stomach
                                                    stomach.feed(self)
/spec/models/user_spec.rb                           self.status = "full"
                                                  end
describe User do
  let(:user) { FactoryGirl.create(:user) }




                  We need to test that feed is called
Complete spec
                                                  def feed_stomach
                                                    stomach.feed(self)
/spec/models/user_spec.rb                           self.status = "full"
                                                  end
describe User do
  let(:user) { FactoryGirl.create(:user) }

   describe '#feed_stomach' do




                  We need to test that feed is called
Complete spec
                                                  def feed_stomach
                                                    stomach.feed(self)
/spec/models/user_spec.rb                           self.status = "full"
                                                  end
describe User do
  let(:user) { FactoryGirl.create(:user) }

   describe '#feed_stomach' do
     it 'set the status to full' do




                  We need to test that feed is called
Complete spec
                                                  def feed_stomach
                                                    stomach.feed(self)
/spec/models/user_spec.rb                           self.status = "full"
                                                  end
describe User do
  let(:user) { FactoryGirl.create(:user) }

   describe '#feed_stomach' do
     it 'set the status to full' do
       user.stomach.stub(:feed)




                  We need to test that feed is called
Complete spec
                                                  def feed_stomach
                                                    stomach.feed(self)
/spec/models/user_spec.rb                           self.status = "full"
                                                  end
describe User do
  let(:user) { FactoryGirl.create(:user) }

   describe '#feed_stomach' do
     it 'set the status to full' do
       user.stomach.stub(:feed)
       user.feed_stomach




                  We need to test that feed is called
Complete spec
                                                  def feed_stomach
                                                    stomach.feed(self)
/spec/models/user_spec.rb                           self.status = "full"
                                                  end
describe User do
  let(:user) { FactoryGirl.create(:user) }

   describe '#feed_stomach' do
     it 'set the status to full' do
       user.stomach.stub(:feed)
       user.feed_stomach
       user.status.should == "full"



                  We need to test that feed is called
Complete spec
                                                  def feed_stomach
                                                    stomach.feed(self)
/spec/models/user_spec.rb                           self.status = "full"
                                                  end
describe User do
  let(:user) { FactoryGirl.create(:user) }

   describe '#feed_stomach' do
     it 'set the status to full' do
       user.stomach.stub(:feed)
       user.feed_stomach
       user.status.should == "full"
     end

                  We need to test that feed is called
Complete spec
                                                  def feed_stomach
                                                    stomach.feed(self)
/spec/models/user_spec.rb                           self.status = "full"
                                                  end
describe User do
  let(:user) { FactoryGirl.create(:user) }

   describe '#feed_stomach' do
     it 'set the status to full' do
       user.stomach.stub(:feed)
       user.feed_stomach
       user.status.should == "full"
     end
   end
                  We need to test that feed is called
Complete spec
                                                def feed_stomach
                                                  stomach.feed(self)
/spec/models/user_spec.rb                         self.status = "full"
                                                end
describe User do
  let(:user) { FactoryGirl.create(:user) }

  describe '#feed_stomach' do
    it 'set the status to full' do
      user.stomach.stub(:feed)
      user.feed_stomach
      user.status.should == "full"
    end
  end
end             We need to test that feed is called
Mocha flavor
Mocha flavor
/app/models/user.rb

def fb_friends_ids
    user = FbGraph::User.me(self.token)
    user.friends.map { |o| o.raw_attributes[:id] }
end
Mocha flavor
/app/models/user.rb
                                              ["1", "45", "987"]
def fb_friends_ids
    user = FbGraph::User.me(self.token)
    user.friends.map { |o| o.raw_attributes[:id] }
end
Mocha flavor
/app/models/user.rb
                                              ["1", "45", "987"]
def fb_friends_ids
    user = FbGraph::User.me(self.token)
    user.friends.map { |o| o.raw_attributes[:id] }
end


/app/specs/user_spec.rb
Mocha flavor
/app/models/user.rb
                                              ["1", "45", "987"]
def fb_friends_ids
    user = FbGraph::User.me(self.token)
    user.friends.map { |o| o.raw_attributes[:id] }
end


/app/specs/user_spec.rb

it 'calls the Facebook Graph to get friends' do
  FbGraph::User.should_receive(:me).with(user.token)
  .and_return(["1", "45", "987"])
  user.fb_friends_ids
end

          stubs the method + expectation with correct
                            param
                                 return value
Mocha flavor
/app/models/user.rb
                                              ["1", "45", "987"]
def fb_friends_ids
    user = FbGraph::User.me(self.token)
    user.friends.map { |o| o.raw_attributes[:id] }
end


/app/specs/user_spec.rb

it 'calls the Facebook Graph to get friends' do
  FbGraph::User.should_receive(:me).with(user.token)
  .and_return(["1", "45", "987"])
  user.fb_friends_ids
end

          stubs the method + expectation with correct
                            param
                                 return value
Where to go next?
http://rspec.info/
 https://github.com/rspec/rspec
 https://github.com/thoughtbot/shoulda

 http://eggsonbread.com/2010/03/28/my-rspec-
 best-practices-and-tips/
 http://www.rubyinside.com/how-to-rails-3-and-
 rspec-2-4336.html
Rspec & Rails




   Abraham Kuri

Weitere ähnliche Inhalte

Was ist angesagt?

Regexes and-performance-testing
Regexes and-performance-testingRegexes and-performance-testing
Regexes and-performance-testingdoughellmann
 
Simple Photo Processing and Web Display with Perl
Simple Photo Processing and Web Display with PerlSimple Photo Processing and Web Display with Perl
Simple Photo Processing and Web Display with PerlKent Cowgill
 
Active Support Core Extensions (1)
Active Support Core Extensions (1)Active Support Core Extensions (1)
Active Support Core Extensions (1)RORLAB
 
"Coffee Script" in Brief
"Coffee Script" in Brief"Coffee Script" in Brief
"Coffee Script" in BriefNat Weerawan
 
究極のコントローラを目指す
究極のコントローラを目指す究極のコントローラを目指す
究極のコントローラを目指すYasuo Harada
 
Magicke metody v Pythonu
Magicke metody v PythonuMagicke metody v Pythonu
Magicke metody v PythonuJirka Vejrazka
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End DevsRebecca Murphey
 
CakePHPをさらにDRYにする、ドライケーキレシピ akiyan.com 秋田真宏
CakePHPをさらにDRYにする、ドライケーキレシピ akiyan.com 秋田真宏CakePHPをさらにDRYにする、ドライケーキレシピ akiyan.com 秋田真宏
CakePHPをさらにDRYにする、ドライケーキレシピ akiyan.com 秋田真宏Masahiro Akita
 
Introduction to Web Components
Introduction to Web ComponentsIntroduction to Web Components
Introduction to Web ComponentsFelix Arntz
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”apostlion
 
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기Suyeol Jeon
 
RxSwift 시작하기
RxSwift 시작하기RxSwift 시작하기
RxSwift 시작하기Suyeol Jeon
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介Jace Ju
 
Coding for Scale and Sanity
Coding for Scale and SanityCoding for Scale and Sanity
Coding for Scale and SanityJimKellerES
 
Serializing Value Objects-Ara Hacopian
Serializing Value Objects-Ara HacopianSerializing Value Objects-Ara Hacopian
Serializing Value Objects-Ara HacopianSmartLogic
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitRebecca Murphey
 

Was ist angesagt? (20)

Regexes and-performance-testing
Regexes and-performance-testingRegexes and-performance-testing
Regexes and-performance-testing
 
Simple Photo Processing and Web Display with Perl
Simple Photo Processing and Web Display with PerlSimple Photo Processing and Web Display with Perl
Simple Photo Processing and Web Display with Perl
 
Active Support Core Extensions (1)
Active Support Core Extensions (1)Active Support Core Extensions (1)
Active Support Core Extensions (1)
 
"Coffee Script" in Brief
"Coffee Script" in Brief"Coffee Script" in Brief
"Coffee Script" in Brief
 
究極のコントローラを目指す
究極のコントローラを目指す究極のコントローラを目指す
究極のコントローラを目指す
 
I regret nothing
I regret nothingI regret nothing
I regret nothing
 
Magicke metody v Pythonu
Magicke metody v PythonuMagicke metody v Pythonu
Magicke metody v Pythonu
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End Devs
 
BVJS
BVJSBVJS
BVJS
 
CakePHPをさらにDRYにする、ドライケーキレシピ akiyan.com 秋田真宏
CakePHPをさらにDRYにする、ドライケーキレシピ akiyan.com 秋田真宏CakePHPをさらにDRYにする、ドライケーキレシピ akiyan.com 秋田真宏
CakePHPをさらにDRYにする、ドライケーキレシピ akiyan.com 秋田真宏
 
Introduction to Web Components
Introduction to Web ComponentsIntroduction to Web Components
Introduction to Web Components
 
Presentation1
Presentation1Presentation1
Presentation1
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”
 
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
 
RxSwift 시작하기
RxSwift 시작하기RxSwift 시작하기
RxSwift 시작하기
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介
 
Coding for Scale and Sanity
Coding for Scale and SanityCoding for Scale and Sanity
Coding for Scale and Sanity
 
Serializing Value Objects-Ara Hacopian
Serializing Value Objects-Ara HacopianSerializing Value Objects-Ara Hacopian
Serializing Value Objects-Ara Hacopian
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development Toolkit
 
Headless Js Testing
Headless Js TestingHeadless Js Testing
Headless Js Testing
 

Ähnlich wie RSpec and Rails testing guide

Building Your First Widget
Building Your First WidgetBuilding Your First Widget
Building Your First WidgetChris Wilcoxson
 
RSpec best practice - avoid using before and let
RSpec best practice - avoid using before and letRSpec best practice - avoid using before and let
RSpec best practice - avoid using before and letBruce Li
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model BasicsJames Gray
 
How We UITest with GraphQL
How We UITest with GraphQL How We UITest with GraphQL
How We UITest with GraphQL hayato iida
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Introzhang tao
 
Perl: Hate it for the Right Reasons
Perl: Hate it for the Right ReasonsPerl: Hate it for the Right Reasons
Perl: Hate it for the Right ReasonsMatt Follett
 
Backbone js
Backbone jsBackbone js
Backbone jsrstankov
 
Typowanie nominalne w TypeScript
Typowanie nominalne w TypeScriptTypowanie nominalne w TypeScript
Typowanie nominalne w TypeScriptThe Software House
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worldsChristopher Spring
 
TypeScriptで書くAngularJS @ GDG神戸2014.8.23
TypeScriptで書くAngularJS @ GDG神戸2014.8.23TypeScriptで書くAngularJS @ GDG神戸2014.8.23
TypeScriptで書くAngularJS @ GDG神戸2014.8.23Okuno Kentaro
 
Ruby on Rails testing with Rspec
Ruby on Rails testing with RspecRuby on Rails testing with Rspec
Ruby on Rails testing with RspecBunlong Van
 
PHP record- with all programs and output
PHP record- with all programs and outputPHP record- with all programs and output
PHP record- with all programs and outputKavithaK23
 
Ajax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsAjax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsTse-Ching Ho
 
Automated testing with RSpec
Automated testing with RSpecAutomated testing with RSpec
Automated testing with RSpecNascenia IT
 
Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)Vysakh Sreenivasan
 

Ähnlich wie RSpec and Rails testing guide (20)

BDD de fuera a dentro
BDD de fuera a dentroBDD de fuera a dentro
BDD de fuera a dentro
 
Building Your First Widget
Building Your First WidgetBuilding Your First Widget
Building Your First Widget
 
RSpec best practice - avoid using before and let
RSpec best practice - avoid using before and letRSpec best practice - avoid using before and let
RSpec best practice - avoid using before and let
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model Basics
 
How We UITest with GraphQL
How We UITest with GraphQL How We UITest with GraphQL
How We UITest with GraphQL
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Intro
 
Perl: Hate it for the Right Reasons
Perl: Hate it for the Right ReasonsPerl: Hate it for the Right Reasons
Perl: Hate it for the Right Reasons
 
Backbone js
Backbone jsBackbone js
Backbone js
 
Typowanie nominalne w TypeScript
Typowanie nominalne w TypeScriptTypowanie nominalne w TypeScript
Typowanie nominalne w TypeScript
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worlds
 
TDC 2015 - DSLs em Ruby
TDC 2015 - DSLs em RubyTDC 2015 - DSLs em Ruby
TDC 2015 - DSLs em Ruby
 
Django - sql alchemy - jquery
Django - sql alchemy - jqueryDjango - sql alchemy - jquery
Django - sql alchemy - jquery
 
TypeScriptで書くAngularJS @ GDG神戸2014.8.23
TypeScriptで書くAngularJS @ GDG神戸2014.8.23TypeScriptで書くAngularJS @ GDG神戸2014.8.23
TypeScriptで書くAngularJS @ GDG神戸2014.8.23
 
Ruby on Rails testing with Rspec
Ruby on Rails testing with RspecRuby on Rails testing with Rspec
Ruby on Rails testing with Rspec
 
PHP record- with all programs and output
PHP record- with all programs and outputPHP record- with all programs and output
PHP record- with all programs and output
 
Ajax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsAjax nested form and ajax upload in rails
Ajax nested form and ajax upload in rails
 
Django
DjangoDjango
Django
 
Factory Girl
Factory GirlFactory Girl
Factory Girl
 
Automated testing with RSpec
Automated testing with RSpecAutomated testing with RSpec
Automated testing with RSpec
 
Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)
 

Mehr von Icalia Labs

Building an Api the Right Way
Building an Api the Right WayBuilding an Api the Right Way
Building an Api the Right WayIcalia Labs
 
Agile practices for management
Agile practices for managementAgile practices for management
Agile practices for managementIcalia Labs
 
Building something out of Nothing
Building something out of NothingBuilding something out of Nothing
Building something out of NothingIcalia Labs
 
Furatto tertulia
Furatto tertuliaFuratto tertulia
Furatto tertuliaIcalia Labs
 
Simple but Useful Design Principles.
Simple but Useful Design Principles.Simple but Useful Design Principles.
Simple but Useful Design Principles.Icalia Labs
 
Your time saving front end workflow
Your time saving front end workflowYour time saving front end workflow
Your time saving front end workflowIcalia Labs
 
Customer Experience Basics
Customer Experience BasicsCustomer Experience Basics
Customer Experience BasicsIcalia Labs
 
Introduction to Swift programming language.
Introduction to Swift programming language.Introduction to Swift programming language.
Introduction to Swift programming language.Icalia Labs
 
Time Hacks for Work
Time Hacks for WorkTime Hacks for Work
Time Hacks for WorkIcalia Labs
 
Culture in a team
Culture in a teamCulture in a team
Culture in a teamIcalia Labs
 
Presentacion vim
Presentacion vimPresentacion vim
Presentacion vimIcalia Labs
 
Using github development process in your company
Using github development process in your companyUsing github development process in your company
Using github development process in your companyIcalia Labs
 
The Art of Pitching
The Art of PitchingThe Art of Pitching
The Art of PitchingIcalia Labs
 
Rails Best Practices
Rails Best PracticesRails Best Practices
Rails Best PracticesIcalia Labs
 
Introduccion meteor.js
Introduccion meteor.jsIntroduccion meteor.js
Introduccion meteor.jsIcalia Labs
 

Mehr von Icalia Labs (16)

Building an Api the Right Way
Building an Api the Right WayBuilding an Api the Right Way
Building an Api the Right Way
 
Agile practices for management
Agile practices for managementAgile practices for management
Agile practices for management
 
Building something out of Nothing
Building something out of NothingBuilding something out of Nothing
Building something out of Nothing
 
Furatto tertulia
Furatto tertuliaFuratto tertulia
Furatto tertulia
 
Simple but Useful Design Principles.
Simple but Useful Design Principles.Simple but Useful Design Principles.
Simple but Useful Design Principles.
 
Your time saving front end workflow
Your time saving front end workflowYour time saving front end workflow
Your time saving front end workflow
 
Customer Experience Basics
Customer Experience BasicsCustomer Experience Basics
Customer Experience Basics
 
Introduction to Swift programming language.
Introduction to Swift programming language.Introduction to Swift programming language.
Introduction to Swift programming language.
 
Time Hacks for Work
Time Hacks for WorkTime Hacks for Work
Time Hacks for Work
 
Culture in a team
Culture in a teamCulture in a team
Culture in a team
 
Curso rails
Curso railsCurso rails
Curso rails
 
Presentacion vim
Presentacion vimPresentacion vim
Presentacion vim
 
Using github development process in your company
Using github development process in your companyUsing github development process in your company
Using github development process in your company
 
The Art of Pitching
The Art of PitchingThe Art of Pitching
The Art of Pitching
 
Rails Best Practices
Rails Best PracticesRails Best Practices
Rails Best Practices
 
Introduccion meteor.js
Introduccion meteor.jsIntroduccion meteor.js
Introduccion meteor.js
 

Kürzlich hochgeladen

A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 

Kürzlich hochgeladen (20)

A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 

RSpec and Rails testing guide

  • 1. Rspec and Rails Abraham Kuri
  • 2. Table of Contents 01 Rails setup 02 Expectations & Matchers 03 Shoulda & DRY Specs 04 Context & Describe blocks 05 Before block 06 Stub & Mock 07 Where to go next?
  • 5. Rails Setup $ rails new <app_name> --skip-test-unit
  • 6. Rails Setup $ rails new <app_name> --skip-test-unit Gemfile: group :test, :development do gem 'rspec-rails' gem "factory_girl_rails" gem 'ffaker' end
  • 7. Rails Setup $ rails new <app_name> --skip-test-unit Gemfile: group :test, :development do gem 'rspec-rails' gem "factory_girl_rails" gem 'ffaker' end
  • 8. Rails Setup $ rails new <app_name> --skip-test-unit Gemfile: group :test, :development do gem 'rspec-rails' gem "factory_girl_rails" gem 'ffaker' end
  • 9. Rails Setup $ rails new <app_name> --skip-test-unit Gemfile: group :test, :development do gem 'rspec-rails' gem "factory_girl_rails" gem 'ffaker' end $ bundle install
  • 10. Rails Setup $ rails new <app_name> --skip-test-unit Gemfile: group :test, :development do gem 'rspec-rails' gem "factory_girl_rails" gem 'ffaker' end $ bundle install $ rails g rspec:install
  • 13. Expectations & Matchers ‣ user_spec.rb describe User do let(:user) { FactoryGirl.create(:user) } subject { user } it 'should not be valid without a name' do user.name = nil user.should_not == nil end end
  • 14. Expectations & Matchers ‣ user_spec.rb describe User do let(:user) { FactoryGirl.create(:user) } subject { user } it 'should not be valid without a name' do user.name = nil user.should_not == nil end end
  • 15. Expectations & Matchers ‣ user_spec.rb describe User do let(:user) { FactoryGirl.create(:user) } subject { user } it 'should not be valid without a name' do user.name = nil modifier user.should_not == nil end end
  • 16. Expectations & Matchers ‣ user_spec.rb describe User do let(:user) { FactoryGirl.create(:user) } subject { user } it 'should not be valid without a name' do user.name = nil modifier user.should_not == nil end end
  • 17. Expectations & Matchers ‣ user_spec.rb describe User do let(:user) { FactoryGirl.create(:user) } subject { user } it 'should not be valid without a name' do user.name = nil modifier user.should_not == nil end end matcher
  • 18. Expectations & Matchers ‣ user_spec.rb describe User do let(:user) { FactoryGirl.create(:user) } subject { user } it 'should not be valid without a name' do user.name = nil modifier user.should_not == nil end end matcher
  • 19. Expectations & Matchers ‣ user_spec.rb describe User do let(:user) { FactoryGirl.create(:user) } subject { user } it 'should not be valid without a name' do user.name = nil modifier user.should_not == nil end end matcher
  • 20. Expectations & Matchers ‣ user_spec.rb describe User do let(:user) { FactoryGirl.create(:user) } subject { user } it 'should not be valid without a name' do user.name = nil modifier user.should_not == nil end end matcher
  • 21. Expectations & Matchers ‣ user_spec.rb describe User do let(:user) { FactoryGirl.create(:user) } subject { user } it 'should not be valid without a name' do user.name = nil modifier user.should_not == nil end end matcher describe User do let(:user) { FactoryGirl.create(:user) } subject { user } its(:name) { should_not be_nil } end
  • 22. Expectations & Matchers ‣ user_spec.rb describe User do let(:user) { FactoryGirl.create(:user) } subject { user } it 'should not be valid without a name' do user.name = nil modifier user.should_not == nil end end matcher describe User do let(:user) { FactoryGirl.create(:user) } subject { user } its(:name) { should_not be_nil } end
  • 24. Other matchers user.name.should == "Abraham" user.friends.should > 3 user.alive.should == true user.alive.should_not == false user.girlfriend.should == nil user.should be_alive have(n) user.friends.should include(other_user) have_at_least(n) have_at_most(n) user.should have(2).arms
  • 25. Other matchers user.name.should == "Abraham" user.friends.should > 3 user.alive.should == true user.alive.should be_true user.alive.should_not == false user.girlfriend.should == nil user.should be_alive have(n) user.friends.should include(other_user) have_at_least(n) have_at_most(n) user.should have(2).arms
  • 26. Other matchers user.name.should == "Abraham" user.friends.should > 3 user.alive.should == true user.alive.should be_true user.alive.should_not == false user.alive.should_not be_false user.girlfriend.should == nil user.should be_alive have(n) user.friends.should include(other_user) have_at_least(n) have_at_most(n) user.should have(2).arms
  • 27. Other matchers user.name.should == "Abraham" user.friends.should > 3 user.alive.should == true user.alive.should be_true user.alive.should_not == false user.alive.should_not be_false user.girlfriend.should == nil user.alive.should be_nil user.should be_alive have(n) user.friends.should include(other_user) have_at_least(n) have_at_most(n) user.should have(2).arms
  • 28. Shoulda to the rescue
  • 29. Shoulda to the rescue
  • 30. Shoulda to the rescue describe User do let(:user) { FactoryGirl.create(:user) } subject { user } its(:name) { should_not be_nil } end
  • 31. Shoulda to the rescue describe User do let(:user) { FactoryGirl.create(:user) } subject { user } its(:name) { should_not be_nil } end
  • 32. Shoulda to the rescue describe User do let(:user) { FactoryGirl.create(:user) } subject { user } its(:name) { should_not be_nil } end it { should validate_presence_of(:name) }
  • 33. Shoulda to the rescue describe User do let(:user) { FactoryGirl.create(:user) } subject { user } its(:name) { should_not be_nil } end it { should validate_presence_of(:name) } it { should validate_uniqueness_of(:email) } it { should have_many(:friends).through(:friendship) }
  • 34. Shoulda to the rescue describe User do let(:user) { FactoryGirl.create(:user) } subject { user } its(:name) { should_not be_nil } end it { should validate_presence_of(:name) } it { should validate_uniqueness_of(:email) } it { should have_many(:friends).through(:friendship) } it { should belong_to(:user)}
  • 36. Context & Describe Blocks describe User do describe 'when sleep' do it 'snores' describe 'with a soft pillow' do it 'still snores' it 'have good dreams' end end end
  • 37. Context & Describe Blocks describe User do describe 'when sleep' do it 'snores' describe 'with a soft pillow' do it 'still snores' it 'have good dreams' end end end
  • 38. Context & Describe Blocks describe User do describe 'when sleep' do it 'snores' describe 'with a soft pillow' do it 'still snores' it 'have good dreams' end end end Use context instead of describe
  • 39. Context & Describe Blocks describe User do describe 'when sleep' do it 'snores' describe 'with a soft pillow' do it 'still snores' it 'have good dreams' end end end Use context instead of describe describe User do context 'when sleep' do it 'snores' context 'with a soft pillow' do it 'still snores' it 'have good dreams' end end end
  • 40. Context & Describe Blocks describe User do describe 'when sleep' do it 'snores' describe 'with a soft pillow' do it 'still snores' it 'have good dreams' end end end Use context instead of describe describe User do context 'when sleep' do it 'snores' context 'with a soft pillow' do it 'still snores' it 'have good dreams' end end end
  • 42. Before block describe 'friends names' do context 'when has friends' do it 'should have 3 friends' do 3.times { user.friends << FactoryGirl.create(:friend) } user.should have(3).friends end it 'should return friend names' do 3.times { user.friends << FactoryGirl.create(:friend) } user.friend_names.should == user.friends.map(&:name) end end end
  • 43. Before block describe 'friends names' do context 'when has friends' do it 'should have 3 friends' do 3.times { user.friends << FactoryGirl.create(:friend) } user.should have(3).friends end it 'should return friend names' do 3.times { user.friends << FactoryGirl.create(:friend) } user.friend_names.should == user.friends.map(&:name) end end end
  • 44. Before block describe 'friends names' do context 'when has friends' do it 'should have 3 friends' do 3.times { user.friends << FactoryGirl.create(:friend) } user.should have(3).friends end it 'should return friend names' do 3.times { user.friends << FactoryGirl.create(:friend) } user.friend_names.should == user.friends.map(&:name) end end end Let’s be more DRY
  • 45. Before block describe 'friends names' do context 'when has friends' do it 'should have 3 friends' do 3.times { user.friends << FactoryGirl.create(:friend) } user.should have(3).friends end it 'should return friend names' do 3.times { user.friends << FactoryGirl.create(:friend) } user.friend_names.should == user.friends.map(&:name) end end end Let’s be more DRY describe 'friends names' do
  • 46. Before block describe 'friends names' do context 'when has friends' do it 'should have 3 friends' do 3.times { user.friends << FactoryGirl.create(:friend) } user.should have(3).friends end it 'should return friend names' do 3.times { user.friends << FactoryGirl.create(:friend) } user.friend_names.should == user.friends.map(&:name) end end end Let’s be more DRY describe 'friends names' do context 'when has friends' do
  • 47. Before block describe 'friends names' do context 'when has friends' do it 'should have 3 friends' do 3.times { user.friends << FactoryGirl.create(:friend) } user.should have(3).friends end it 'should return friend names' do 3.times { user.friends << FactoryGirl.create(:friend) } user.friend_names.should == user.friends.map(&:name) end end end Let’s be more DRY describe 'friends names' do context 'when has friends' do before do
  • 48. Before block describe 'friends names' do context 'when has friends' do it 'should have 3 friends' do 3.times { user.friends << FactoryGirl.create(:friend) } user.should have(3).friends end it 'should return friend names' do 3.times { user.friends << FactoryGirl.create(:friend) } user.friend_names.should == user.friends.map(&:name) end end end Let’s be more DRY describe 'friends names' do context 'when has friends' do before do 3.times { user.friends << FactoryGirl.create(:friend) }
  • 49. Before block describe 'friends names' do context 'when has friends' do it 'should have 3 friends' do 3.times { user.friends << FactoryGirl.create(:friend) } user.should have(3).friends end it 'should return friend names' do 3.times { user.friends << FactoryGirl.create(:friend) } user.friend_names.should == user.friends.map(&:name) end end end Let’s be more DRY describe 'friends names' do context 'when has friends' do before do 3.times { user.friends << FactoryGirl.create(:friend) } end
  • 50. Before block describe 'friends names' do context 'when has friends' do it 'should have 3 friends' do 3.times { user.friends << FactoryGirl.create(:friend) } user.should have(3).friends end it 'should return friend names' do 3.times { user.friends << FactoryGirl.create(:friend) } user.friend_names.should == user.friends.map(&:name) end end end Let’s be more DRY describe 'friends names' do context 'when has friends' do before do 3.times { user.friends << FactoryGirl.create(:friend) } end it { should have(3).friends }
  • 51. Before block describe 'friends names' do context 'when has friends' do it 'should have 3 friends' do 3.times { user.friends << FactoryGirl.create(:friend) } user.should have(3).friends end it 'should return friend names' do 3.times { user.friends << FactoryGirl.create(:friend) } user.friend_names.should == user.friends.map(&:name) end end end Let’s be more DRY describe 'friends names' do context 'when has friends' do before do 3.times { user.friends << FactoryGirl.create(:friend) } end it { should have(3).friends } its(:friend_names) { should == user.friends.map(&:name) }
  • 52. Before block describe 'friends names' do context 'when has friends' do it 'should have 3 friends' do 3.times { user.friends << FactoryGirl.create(:friend) } user.should have(3).friends end it 'should return friend names' do 3.times { user.friends << FactoryGirl.create(:friend) } user.friend_names.should == user.friends.map(&:name) end end end Let’s be more DRY describe 'friends names' do context 'when has friends' do before do 3.times { user.friends << FactoryGirl.create(:friend) } end it { should have(3).friends } its(:friend_names) { should == user.friends.map(&:name) } end
  • 53. Before block describe 'friends names' do context 'when has friends' do it 'should have 3 friends' do 3.times { user.friends << FactoryGirl.create(:friend) } user.should have(3).friends end it 'should return friend names' do 3.times { user.friends << FactoryGirl.create(:friend) } user.friend_names.should == user.friends.map(&:name) end end end Let’s be more DRY describe 'friends names' do context 'when has friends' do before do 3.times { user.friends << FactoryGirl.create(:friend) } end it { should have(3).friends } its(:friend_names) { should == user.friends.map(&:name) } end end
  • 54. Before block describe 'friends names' do context 'when has friends' do it 'should have 3 friends' do 3.times { user.friends << FactoryGirl.create(:friend) } user.should have(3).friends end it 'should return friend names' do 3.times { user.friends << FactoryGirl.create(:friend) } user.friend_names.should == user.friends.map(&:name) end end end Let’s be more DRY describe 'friends names' do context 'when has friends' do before do 3.times { user.friends << FactoryGirl.create(:friend) } end it { should have(3).friends } its(:friend_names) { should == user.friends.map(&:name) } end end
  • 55. Before block describe 'friends names' do context 'when has friends' do it 'should have 3 friends' do 3.times { user.friends << FactoryGirl.create(:friend) } user.should have(3).friends end it 'should return friend names' do 3.times { user.friends << FactoryGirl.create(:friend) } user.friend_names.should == user.friends.map(&:name) end end end Let’s be more DRY describe 'friends names' do context 'when has friends' do before do 3.times { user.friends << FactoryGirl.create(:friend) } end it { should have(3).friends } its(:friend_names) { should == user.friends.map(&:name) } end end Much better
  • 57. Stubs & Mocking ‣ Stubs For replacing a method with code that return a specified result
  • 58. Stubs & Mocking ‣ Stubs For replacing a method with code that return a specified result ‣ Mocks A stub with an expectations that the method gets called
  • 60. Stub it out app/models/user.rb class User < ActiveRecord::Base has_one :stomach def feed_stomach stomach.feed(self) self.status = "full" end end
  • 61. Stub it out User feed_stomach app/models/user.rb class User < ActiveRecord::Base has_one :stomach def feed_stomach stomach.feed(self) self.status = "full" end end
  • 62. Stub it out User feed_stomach app/models/user.rb class User < ActiveRecord::Base has_one :stomach def feed_stomach stomach.feed(self) self.status = "full" end end
  • 63. Stub it out User Stomach feed_stomach def feed(*args) return nil end app/models/user.rb class User < ActiveRecord::Base has_one :stomach def feed_stomach stomach.feed(self) self.status = "full" end end
  • 64. Stub it out User Stomach feed_stomach def feed(*args) return nil end user.stomach.stub(:feed_stomach) app/models/user.rb class User < ActiveRecord::Base has_one :stomach def feed_stomach stomach.feed(self) self.status = "full" end end
  • 66. Complete spec def feed_stomach stomach.feed(self) self.status = "full" end
  • 67. Complete spec def feed_stomach stomach.feed(self) /spec/models/user_spec.rb self.status = "full" end We need to test that feed is called
  • 68. Complete spec def feed_stomach stomach.feed(self) /spec/models/user_spec.rb self.status = "full" end describe User do We need to test that feed is called
  • 69. Complete spec def feed_stomach stomach.feed(self) /spec/models/user_spec.rb self.status = "full" end describe User do let(:user) { FactoryGirl.create(:user) } We need to test that feed is called
  • 70. Complete spec def feed_stomach stomach.feed(self) /spec/models/user_spec.rb self.status = "full" end describe User do let(:user) { FactoryGirl.create(:user) } We need to test that feed is called
  • 71. Complete spec def feed_stomach stomach.feed(self) /spec/models/user_spec.rb self.status = "full" end describe User do let(:user) { FactoryGirl.create(:user) } describe '#feed_stomach' do We need to test that feed is called
  • 72. Complete spec def feed_stomach stomach.feed(self) /spec/models/user_spec.rb self.status = "full" end describe User do let(:user) { FactoryGirl.create(:user) } describe '#feed_stomach' do it 'set the status to full' do We need to test that feed is called
  • 73. Complete spec def feed_stomach stomach.feed(self) /spec/models/user_spec.rb self.status = "full" end describe User do let(:user) { FactoryGirl.create(:user) } describe '#feed_stomach' do it 'set the status to full' do user.stomach.stub(:feed) We need to test that feed is called
  • 74. Complete spec def feed_stomach stomach.feed(self) /spec/models/user_spec.rb self.status = "full" end describe User do let(:user) { FactoryGirl.create(:user) } describe '#feed_stomach' do it 'set the status to full' do user.stomach.stub(:feed) user.feed_stomach We need to test that feed is called
  • 75. Complete spec def feed_stomach stomach.feed(self) /spec/models/user_spec.rb self.status = "full" end describe User do let(:user) { FactoryGirl.create(:user) } describe '#feed_stomach' do it 'set the status to full' do user.stomach.stub(:feed) user.feed_stomach user.status.should == "full" We need to test that feed is called
  • 76. Complete spec def feed_stomach stomach.feed(self) /spec/models/user_spec.rb self.status = "full" end describe User do let(:user) { FactoryGirl.create(:user) } describe '#feed_stomach' do it 'set the status to full' do user.stomach.stub(:feed) user.feed_stomach user.status.should == "full" end We need to test that feed is called
  • 77. Complete spec def feed_stomach stomach.feed(self) /spec/models/user_spec.rb self.status = "full" end describe User do let(:user) { FactoryGirl.create(:user) } describe '#feed_stomach' do it 'set the status to full' do user.stomach.stub(:feed) user.feed_stomach user.status.should == "full" end end We need to test that feed is called
  • 78. Complete spec def feed_stomach stomach.feed(self) /spec/models/user_spec.rb self.status = "full" end describe User do let(:user) { FactoryGirl.create(:user) } describe '#feed_stomach' do it 'set the status to full' do user.stomach.stub(:feed) user.feed_stomach user.status.should == "full" end end end We need to test that feed is called
  • 80. Mocha flavor /app/models/user.rb def fb_friends_ids user = FbGraph::User.me(self.token) user.friends.map { |o| o.raw_attributes[:id] } end
  • 81. Mocha flavor /app/models/user.rb ["1", "45", "987"] def fb_friends_ids user = FbGraph::User.me(self.token) user.friends.map { |o| o.raw_attributes[:id] } end
  • 82. Mocha flavor /app/models/user.rb ["1", "45", "987"] def fb_friends_ids user = FbGraph::User.me(self.token) user.friends.map { |o| o.raw_attributes[:id] } end /app/specs/user_spec.rb
  • 83. Mocha flavor /app/models/user.rb ["1", "45", "987"] def fb_friends_ids user = FbGraph::User.me(self.token) user.friends.map { |o| o.raw_attributes[:id] } end /app/specs/user_spec.rb it 'calls the Facebook Graph to get friends' do FbGraph::User.should_receive(:me).with(user.token) .and_return(["1", "45", "987"]) user.fb_friends_ids end stubs the method + expectation with correct param return value
  • 84. Mocha flavor /app/models/user.rb ["1", "45", "987"] def fb_friends_ids user = FbGraph::User.me(self.token) user.friends.map { |o| o.raw_attributes[:id] } end /app/specs/user_spec.rb it 'calls the Facebook Graph to get friends' do FbGraph::User.should_receive(:me).with(user.token) .and_return(["1", "45", "987"]) user.fb_friends_ids end stubs the method + expectation with correct param return value
  • 85. Where to go next? http://rspec.info/ https://github.com/rspec/rspec https://github.com/thoughtbot/shoulda http://eggsonbread.com/2010/03/28/my-rspec- best-practices-and-tips/ http://www.rubyinside.com/how-to-rails-3-and- rspec-2-4336.html
  • 86. Rspec & Rails Abraham Kuri

Hinweis der Redaktion

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n