Your SlideShare is downloading. ×
Rspec and Rails
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Rspec and Rails

1,805
views

Published on

This is a presentation which shows how to unit test with rspec, factory girl in a rails project

This is a presentation which shows how to unit test with rspec, factory girl in a rails project

Published in: Technology

0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,805
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
70
Comments
0
Likes
5
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript

    • 1. Rspec and Rails Abraham Kuri
    • 2. Table of Contents01 Rails setup02 Expectations & Matchers03 Shoulda & DRY Specs04 Context & Describe blocks05 Before block06 Stub & Mock07 Where to go next?
    • 3. Rails Setup
    • 4. Rails Setup
    • 5. Rails Setup$ rails new <app_name> --skip-test-unit
    • 6. Rails Setup$ rails new <app_name> --skip-test-unitGemfile:group :test, :development do gem rspec-rails gem "factory_girl_rails" gem ffakerend
    • 7. Rails Setup$ rails new <app_name> --skip-test-unitGemfile:group :test, :development do gem rspec-rails gem "factory_girl_rails" gem ffakerend
    • 8. Rails Setup$ rails new <app_name> --skip-test-unitGemfile:group :test, :development do gem rspec-rails gem "factory_girl_rails" gem ffakerend
    • 9. Rails Setup$ rails new <app_name> --skip-test-unitGemfile:group :test, :development do gem rspec-rails gem "factory_girl_rails" gem ffakerend$ bundle install
    • 10. Rails Setup$ rails new <app_name> --skip-test-unitGemfile:group :test, :development do gem rspec-rails gem "factory_girl_rails" gem ffakerend$ bundle install$ rails g rspec:install
    • 11. Expectations & Matchers‣ user_spec.rb
    • 12. Expectations & Matchers‣ user_spec.rb
    • 13. Expectations & Matchers‣ user_spec.rbdescribe 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 endend
    • 14. Expectations & Matchers‣ user_spec.rbdescribe 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 endend
    • 15. Expectations & Matchers‣ user_spec.rbdescribe 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 endend
    • 16. Expectations & Matchers‣ user_spec.rbdescribe 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 endend
    • 17. Expectations & Matchers‣ user_spec.rbdescribe 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 endend matcher
    • 18. Expectations & Matchers‣ user_spec.rbdescribe 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 endend matcher
    • 19. Expectations & Matchers‣ user_spec.rbdescribe 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 endend matcher
    • 20. Expectations & Matchers‣ user_spec.rbdescribe 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 endend matcher
    • 21. Expectations & Matchers‣ user_spec.rbdescribe 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 endend matcher describe User do let(:user) { FactoryGirl.create(:user) } subject { user } its(:name) { should_not be_nil } end
    • 22. Expectations & Matchers‣ user_spec.rbdescribe 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 endend matcher describe User do let(:user) { FactoryGirl.create(:user) } subject { user } its(:name) { should_not be_nil } end
    • 23. Other matchers
    • 24. Other matchersuser.name.should == "Abraham"user.friends.should > 3user.alive.should == trueuser.alive.should_not == falseuser.girlfriend.should == niluser.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 matchersuser.name.should == "Abraham"user.friends.should > 3user.alive.should == true user.alive.should be_trueuser.alive.should_not == falseuser.girlfriend.should == niluser.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 matchersuser.name.should == "Abraham"user.friends.should > 3user.alive.should == true user.alive.should be_trueuser.alive.should_not == false user.alive.should_not be_falseuser.girlfriend.should == niluser.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 matchersuser.name.should == "Abraham"user.friends.should > 3user.alive.should == true user.alive.should be_trueuser.alive.should_not == false user.alive.should_not be_falseuser.girlfriend.should == nil user.alive.should be_niluser.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 rescuedescribe User do let(:user) { FactoryGirl.create(:user) } subject { user } its(:name) { should_not be_nil }end
    • 31. Shoulda to the rescuedescribe User do let(:user) { FactoryGirl.create(:user) } subject { user } its(:name) { should_not be_nil }end
    • 32. Shoulda to the rescuedescribe User do let(:user) { FactoryGirl.create(:user) } subject { user } its(:name) { should_not be_nil }endit { should validate_presence_of(:name) }
    • 33. Shoulda to the rescuedescribe User do let(:user) { FactoryGirl.create(:user) } subject { user } its(:name) { should_not be_nil }endit { should validate_presence_of(:name) }it { should validate_uniqueness_of(:email) }it { should have_many(:friends).through(:friendship) }
    • 34. Shoulda to the rescuedescribe User do let(:user) { FactoryGirl.create(:user) } subject { user } its(:name) { should_not be_nil }endit { should validate_presence_of(:name) }it { should validate_uniqueness_of(:email) }it { should have_many(:friends).through(:friendship) }it { should belong_to(:user)}
    • 35. Context & Describe Blocks
    • 36. Context & Describe Blocksdescribe User do describe when sleep do it snores describe with a soft pillow do it still snores it have good dreams end endend
    • 37. Context & Describe Blocksdescribe User do describe when sleep do it snores describe with a soft pillow do it still snores it have good dreams end endend
    • 38. Context & Describe Blocksdescribe User do describe when sleep do it snores describe with a soft pillow do it still snores it have good dreams end endend Use context instead of describe
    • 39. Context & Describe Blocksdescribe User do describe when sleep do it snores describe with a soft pillow do it still snores it have good dreams end endend Use context instead of describedescribe User do context when sleep do it snores context with a soft pillow do it still snores it have good dreams end endend
    • 40. Context & Describe Blocksdescribe User do describe when sleep do it snores describe with a soft pillow do it still snores it have good dreams end endend Use context instead of describedescribe User do context when sleep do it snores context with a soft pillow do it still snores it have good dreams end endend
    • 41. Before block
    • 42. Before blockdescribe 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 endend
    • 43. Before blockdescribe 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 endend
    • 44. Before blockdescribe 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 endend Let’s be more DRY
    • 45. Before blockdescribe 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 endend Let’s be more DRYdescribe friends names do
    • 46. Before blockdescribe 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 endend Let’s be more DRYdescribe friends names do context when has friends do
    • 47. Before blockdescribe 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 endend Let’s be more DRYdescribe friends names do context when has friends do before do
    • 48. Before blockdescribe 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 endend Let’s be more DRYdescribe friends names do context when has friends do before do 3.times { user.friends << FactoryGirl.create(:friend) }
    • 49. Before blockdescribe 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 endend Let’s be more DRYdescribe friends names do context when has friends do before do 3.times { user.friends << FactoryGirl.create(:friend) } end
    • 50. Before blockdescribe 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 endend Let’s be more DRYdescribe 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 blockdescribe 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 endend Let’s be more DRYdescribe 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 blockdescribe 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 endend Let’s be more DRYdescribe 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 blockdescribe 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 endend Let’s be more DRYdescribe 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) } endend
    • 54. Before blockdescribe 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 endend Let’s be more DRYdescribe 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) } endend
    • 55. Before blockdescribe 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 endend Let’s be more DRYdescribe 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) } endend Much better
    • 56. Stubs & Mocking
    • 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
    • 59. Stub it out
    • 60. Stub it outapp/models/user.rbclass User < ActiveRecord::Base has_one :stomach def feed_stomach stomach.feed(self) self.status = "full" endend
    • 61. Stub it out User feed_stomachapp/models/user.rbclass User < ActiveRecord::Base has_one :stomach def feed_stomach stomach.feed(self) self.status = "full" endend
    • 62. Stub it out User feed_stomachapp/models/user.rbclass User < ActiveRecord::Base has_one :stomach def feed_stomach stomach.feed(self) self.status = "full" endend
    • 63. Stub it out User Stomach feed_stomach def feed(*args) return nil endapp/models/user.rbclass User < ActiveRecord::Base has_one :stomach def feed_stomach stomach.feed(self) self.status = "full" endend
    • 64. Stub it out User Stomach feed_stomach def feed(*args) return nil end user.stomach.stub(:feed_stomach)app/models/user.rbclass User < ActiveRecord::Base has_one :stomach def feed_stomach stomach.feed(self) self.status = "full" endend
    • 65. Complete spec
    • 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" enddescribe 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" enddescribe 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" enddescribe 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" enddescribe 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" enddescribe 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" enddescribe 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" enddescribe 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" enddescribe 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" enddescribe 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" enddescribe 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" enddescribe 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 endend We need to test that feed is called
    • 79. Mocha flavor
    • 80. Mocha flavor/app/models/user.rbdef 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.rbit calls the Facebook Graph to get friends do FbGraph::User.should_receive(:me).with(user.token) .and_return(["1", "45", "987"]) user.fb_friends_idsend 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.rbit calls the Facebook Graph to get friends do FbGraph::User.should_receive(:me).with(user.token) .and_return(["1", "45", "987"]) user.fb_friends_idsend 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