getting answers to your testing questions
TRANSCRIPT
![Page 1: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/1.jpg)
Getting Answers to Your Testing Questions
Josh Justice
![Page 2: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/2.jpg)
CodingItWrong
CodingItWrong
![Page 3: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/3.jpg)
@bignerdranch bignerdranch.com
![Page 4: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/4.jpg)
Ruby on Rails course June 27–July 1
bit.ly/nerdrails
![Page 5: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/5.jpg)
How do I get started testing? 🤔
![Page 6: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/6.jpg)
Questions! 🤔• Do I write the test or production code first?
• What do I test first?
• How many acceptance/unit tests do I write?
• How much test code do I write at a time? Production code?
• Do I test every line of code and configuration?
• How much do I use test doubles? What do I test for?
![Page 7: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/7.jpg)
Everyone agrees! 🙈
![Page 8: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/8.jpg)
"Unit tests are good!" "Unit tests are bad!" "Mocks are good!" "Mocks are bad!"
😩
![Page 9: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/9.jpg)
![Page 10: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/10.jpg)
What if we didn’t have to worry about all those
questions at once?
![Page 11: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/11.jpg)
Test-Driven Development:
An approach to testing that provides a consistent set of answers to those questions.
![Page 12: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/12.jpg)
“TDD is dead”…?
![Page 13: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/13.jpg)
Too rigid?
• Not “follow this exactly or you’re a bad developer.”
• Not “this is the only way it can be done.”
• Give it a whole-hearted try. Then you’ll know when to apply it and when not to.
• Or, just take a principle or two and see if they help.
![Page 14: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/14.jpg)
Goals
• Show TDD applied to a small real-world example.
• Show how it answers those questions about how to get started in testing.
• Motivate you to try it if you haven’t (or if you haven’t strictly).
![Page 15: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/15.jpg)
Not Goals
• Convince you testing is a good idea.
• Introduce testing concepts and terms.
• Provide rationale for individual points of TDD.
![Page 16: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/16.jpg)
learntdd.in/rails
![Page 17: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/17.jpg)
Requirement: as a user, I want to be able to create a blog post.
(of course)
![Page 18: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/18.jpg)
Do I write the test or production code first?
Write tests first.
🤔
![Page 19: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/19.jpg)
Why tests first?
• To make sure there's time to test.
• To make sure your code is covered by tests.
• To make sure your code is easy to test.
• To let tests drive your design.
![Page 20: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/20.jpg)
What do I test first?
Start outside the system.
🤔
![Page 21: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/21.jpg)
How much test do I write at a time?
Write a whole acceptance test for one feature.
🤔
![Page 22: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/22.jpg)
# spec/features/creating_a_blog_post_spec.rb require 'rails_helper'
describe 'Creating a blog post' do
it 'saves and displays the resulting blog post' do visit '/blog_posts/new'
fill_in 'Title', with: 'Hello, World!' fill_in 'Body', with: 'Hello, I say!'
click_on 'Create Blog Post'
blog_post = BlogPost.order("id").last expect(blog_post.title).to eq('Hello, World!') expect(blog_post.body).to eq('Hello, I say!')
expect(page).to have_content('Hello, World!') expect(page).to have_content('Hello, I say!') end
end
![Page 23: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/23.jpg)
# spec/features/creating_a_blog_post_spec.rb require 'rails_helper'
describe 'Creating a blog post' do
it 'saves and displays the resulting blog post' do visit '/blog_posts/new'
fill_in 'Title', with: 'Hello, World!' fill_in 'Body', with: 'Hello, I say!'
click_on 'Create Blog Post'
blog_post = BlogPost.order("id").last expect(blog_post.title).to eq('Hello, World!') expect(blog_post.body).to eq('Hello, I say!')
expect(page).to have_content('Hello, World!') expect(page).to have_content('Hello, I say!') end
end How much do I use test doubles?
In acceptance tests, don’t use test doubles.
🤔
![Page 24: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/24.jpg)
Run the test and watch it fail, to know what to
implement first.
![Page 25: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/25.jpg)
# rspec spec/features/creating_a_blog_post_spec.rbF
Failures:
1) Creating a blog post saves and displays the resulting blog post Failure/Error: visit '/blog_posts/new'
ActionController::RoutingError: No route matches [GET] "/blog_posts/new"
![Page 26: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/26.jpg)
# config/routes.rb Rails.application.routes.draw do resources :blog_posts end
![Page 27: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/27.jpg)
# config/routes.rb Rails.application.routes.draw do resources :blog_posts end
Do I test every line?
No, you can fix trivial errors directly.
🤔
![Page 28: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/28.jpg)
# config/routes.rb Rails.application.routes.draw do resources :blog_posts end
How much production code do I write at a time?
Just enough to fix the current error.
🤔
![Page 29: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/29.jpg)
Red-Green-Refactor
![Page 30: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/30.jpg)
A note on refactoring.
![Page 31: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/31.jpg)
# rspec spec/features/creating_a_blog_post_spec.rbF
Failures:
1) Creating a blog post saves and displays the resulting blog post Failure/Error: visit '/blog_posts/new'
ActionController::RoutingError: uninitialized constant BlogPostsController
![Page 32: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/32.jpg)
# app/controllers/blog_posts_controller.rb class BlogPostsController < ApplicationController end
![Page 33: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/33.jpg)
# rspec spec/features/creating_a_blog_post_spec.rbF
Failures:
1) Creating a blog post saves and displays the resulting blog post Failure/Error: visit '/blog_posts/new'
AbstractController::ActionNotFound: The action 'new' could not be found for BlogPostsController
![Page 34: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/34.jpg)
# app/controllers/blog_posts_controller.rb class BlogPostsController < ApplicationController def new end end
![Page 35: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/35.jpg)
# rspec spec/features/creating_a_blog_post_spec.rbF
Failures:
1) Creating a blog post saves and displays the resulting blog post Failure/Error: visit '/blog_posts/new'
ActionView::MissingTemplate: Missing template blog_posts/new
![Page 36: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/36.jpg)
<%# app/views/blog_posts/new.html.erb %>
![Page 37: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/37.jpg)
# rspec spec/features/creating_a_blog_post_spec.rbF
Failures:
1) Creating a blog post saves and displays the resulting blog post Failure/Error: fill_in 'Title', with: 'Hello, World!'
Capybara::ElementNotFound: Unable to find field "Title"
![Page 38: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/38.jpg)
<%# app/views/blog_posts/new.html.erb %> <%= form_for @blog_post do |f| %> <div> <%= f.label :title %> <%= f.text_field :title %> </div> <div> <%= f.label :body %> <%= f.text_area :body %> </div> <%= f.submit 'Create Blog Post' %> <% end %>
![Page 39: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/39.jpg)
<%# app/views/blog_posts/new.html.erb %> <%= form_for @blog_post do |f| %> <div> <%= f.label :title %> <%= f.text_field :title %> </div> <div> <%= f.label :body %> <%= f.text_area :body %> </div> <%= f.submit 'Create Blog Post' %> <% end %>
How much production code do I write at a time?
Sometimes, more than enough to fix the current error.
🤔
![Page 40: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/40.jpg)
# rspec spec/features/creating_a_blog_post_spec.rbF
Failures:
1) Creating a blog post saves and displays the resulting blog post Failure/Error: <%= form_for @blog_post do |f| %>
ActionView::Template::Error: First argument in form cannot contain nil or be empty
![Page 41: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/41.jpg)
# rspec spec/features/creating_a_blog_post_spec.rbF
Failures:
1) Creating a blog post saves and displays the resulting blog post Failure/Error: <%= form_for @blog_post do |f| %>
ActionView::Template::Error: First argument in form cannot contain nil or be empty
When do I write unit tests?
Step down to a unit test when there are behavioral errors.
🤔
![Page 42: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/42.jpg)
Why unit test when there's already an acceptance test?
![Page 43: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/43.jpg)
Acceptance tests demonstrate external quality: whether the
system works.
![Page 44: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/44.jpg)
Acceptance tests don't demonstrate internal quality: whether the
code is maintainable.
![Page 45: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/45.jpg)
Unit tests expose internal quality. They drive design.
![Page 46: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/46.jpg)
# spec/controllers/blog_posts_controller_spec.rb require 'rails_helper'
describe BlogPostsController do
describe '#new' do it 'returns a blog post' do blog_post = instance_double(BlogPost) expect(BlogPost).to receive(:new).and_return(blog_post) get :new expect(assigns[:blog_post]).to eq(blog_post) end end
end
![Page 47: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/47.jpg)
# spec/controllers/blog_posts_controller_spec.rb require 'rails_helper'
describe BlogPostsController do
describe '#new' do it 'returns a blog post' do blog_post = instance_double(BlogPost) expect(BlogPost).to receive(:new).and_return(blog_post) get :new expect(assigns[:blog_post]).to eq(blog_post) end end
end How much test do I write?
Write only enough unit test to expose the behavioral error.
🤔
![Page 48: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/48.jpg)
# spec/controllers/blog_posts_controller_spec.rb require 'rails_helper'
describe BlogPostsController do
describe '#new' do it 'returns a blog post' do blog_post = instance_double(BlogPost) expect(BlogPost).to receive(:new).and_return(blog_post) get :new expect(assigns[:blog_post]).to eq(blog_post) end end
end How much test do I write?
Specify one behavior per unit test case.
🤔
![Page 49: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/49.jpg)
# spec/controllers/blog_posts_controller_spec.rb require 'rails_helper'
describe BlogPostsController do
describe '#new' do it 'returns a blog post' do blog_post = instance_double(BlogPost) expect(BlogPost).to receive(:new).and_return(blog_post) get :new expect(assigns[:blog_post]).to eq(blog_post) end end
end How much do I use test doubles?
In unit tests, use test doubles in place of any collaborators.
🤔
![Page 50: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/50.jpg)
# spec/controllers/blog_posts_controller_spec.rb require 'rails_helper'
describe BlogPostsController do
describe '#new' do it 'returns a blog post' do blog_post = instance_double(BlogPost) expect(BlogPost).to receive(:new).and_return(blog_post) get :new expect(assigns[:blog_post]).to eq(blog_post) end end
end What do I test for?
In unit tests, behavior, not state. (Mostly.)
🤔
![Page 51: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/51.jpg)
# rspec spec/controllers/blog_posts_controller_spec.rbF
Failures:
1) BlogPostsController#new returns a blog post Failure/Error: blog_post = instance_double(BlogPost)
NameError: uninitialized constant BlogPost
![Page 52: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/52.jpg)
# db/migrate/20160223100510_create_blog_posts.rb class CreateBlogPosts < ActiveRecord::Migration def change create_table :blog_posts do |t| t.string :title t.text :body end end end
# app/models/blog_post.rb class BlogPost < ActiveRecord::Base end
![Page 53: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/53.jpg)
# rspec spec/controllers/blog_posts_controller_spec.rbF
Failures:
1) BlogPostsController#new returns a blog post Failure/Error: expect(assigns[:blog_post]).to eq(blog_post)
expected: #<InstanceDouble(BlogPost) (anonymous)> got: nil
(compared using ==)
![Page 54: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/54.jpg)
# app/controllers/blog_posts_controller.rb class BlogPostsController < ApplicationController def new @blog_post = BlogPost.new end end
![Page 55: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/55.jpg)
# rspec spec/controllers/blog_posts_controller_spec.rb.
Finished in 0.03134 seconds (files took 1.46 seconds to load)1 example, 0 failures
![Page 56: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/56.jpg)
How often do I run which tests?
When the unit test passes, step back up to the acceptance test.
🤔
![Page 57: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/57.jpg)
Two Red-Green-Refactor Loops
![Page 58: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/58.jpg)
# spec/features/creating_a_blog_post_spec.rb require 'rails_helper'
describe 'Creating a blog post' do
it 'saves and displays the resulting blog post' do visit '/blog_posts/new'
fill_in 'Title', with: 'Hello, World!' fill_in 'Body', with: 'Hello, I say!'
click_on 'Create Blog Post'
blog_post = BlogPost.order("id").last expect(blog_post.title).to eq('Hello, World!') expect(blog_post.body).to eq('Hello, I say!')
expect(page).to have_content('Hello, World!') expect(page).to have_content('Hello, I say!') end
end
![Page 59: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/59.jpg)
# rspec spec/features/creating_a_blog_post_spec.rbF
Failures:
1) Creating a blog post saves and displays the resulting blog post Failure/Error: click_on 'Create Blog Post'
AbstractController::ActionNotFound: The action 'create' could not be found for BlogPostsController
![Page 60: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/60.jpg)
# app/controllers/blog_posts_controller.rb class BlogPostsController < ApplicationController def new ... end
def create end end
![Page 61: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/61.jpg)
# rspec spec/features/creating_a_blog_post_spec.rbF
Failures:
1) Creating a blog post saves and displays the resulting blog post Failure/Error: click_on 'Create Blog Post'
ActionView::MissingTemplate: Missing template blog_posts/create
![Page 62: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/62.jpg)
<%# app/views/blog_posts/create.html.erb %>
![Page 63: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/63.jpg)
# rspec spec/features/creating_a_blog_post_spec.rbF
Failures:
1) Creating a blog post saves and displays the resulting blog post Failure/Error: expect(blog_post.title).to eq('Hello, World!')
NoMethodError: undefined method `title' for nil:NilClass
![Page 64: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/64.jpg)
# spec/controllers/blog_posts_controller_spec.rb require 'rails_helper'
describe BlogPostsController do
describe '#new' do ... end
describe '#create' do it 'creates a blog post record' do expect(BlogPost).to receive(:create).with(title: 'My Title', body: 'My Body') post :create, { blog_post: { title: 'My Title', body: 'My Body', } } end end end
![Page 65: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/65.jpg)
# rspec spec/controllers/blog_posts_controller_spec.rb.F
Failures:
1) BlogPostsController#create creates a blog post record Failure/Error: expect(BlogPost).to receive(:create).with(title: 'My Title', body: 'My Body')
(BlogPost(id: integer, title: string, body: text) (class)).create({:title=>"My Title", :body=>"My Body"}) expected: 1 time with arguments: ({:title=>"My Title", :body=>"My Body"}) received: 0 times
![Page 66: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/66.jpg)
# app/controllers/blog_posts_controller.rb class BlogPostsController < ApplicationController ...
def create BlogPost.create(params[:blog_post]) end end
☝😧 Wait for iiiiiiiit…
![Page 67: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/67.jpg)
# rspec spec/controllers/blog_posts_controller_spec.rb..
Finished in 0.02774 seconds (files took 1.53 seconds to load)2 examples, 0 failures
![Page 68: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/68.jpg)
# rspec spec/features/creating_a_blog_post_spec.rbF
Failures:
1) Creating a blog post saves and displays the resulting blog post Failure/Error: BlogPost.create(params[:blog_post])
ActiveModel::ForbiddenAttributesError
![Page 69: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/69.jpg)
# app/controllers/blog_posts_controller.rb class BlogPostsController < ApplicationController ...
def create BlogPost.create(blog_post_params) end
private
def blog_post_params params.require(:blog_post).permit(:title, :body) end end
![Page 70: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/70.jpg)
# rspec spec/features/creating_a_blog_post_spec.rbF
Failures:
1) Creating a blog post saves and displays the resulting blog post Failure/Error: expect(page).to have_content('Hello, World!') expected to find text "Hello, World!" in ""
![Page 71: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/71.jpg)
<%# app/views/blog_posts/create.html.erb %> <h1><%= @blog_post.title %></h1>
<div> <%= @blog_post.body %> </div>
![Page 72: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/72.jpg)
# rspec spec/features/creating_a_blog_post_spec.rbF
Failures:
1) Creating a blog post saves and displays the resulting blog post Failure/Error: <h1><%= @blog_post.title %></h1>
ActionView::Template::Error: undefined method `title' for nil:NilClass
![Page 73: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/73.jpg)
# spec/controllers/blog_posts_controller_spec.rb require 'rails_helper'
describe BlogPostsController do
...
describe '#create' do it 'creates a blog post record' do ... end
it 'returns the new blog post to the view' do blog_post = instance_double(BlogPost) allow(BlogPost).to receive(:create).and_return(blog_post) post :create, { blog_post: { title: 'My Title', body: 'My Body', } } expect(assigns[:blog_post]).to eq(blog_post) end end end
![Page 74: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/74.jpg)
# rspec spec/controllers/blog_posts_controller_spec.rb..F
Failures:
1) BlogPostsController#create returns the new blog post to the view Failure/Error: expect(assigns[:blog_post]).to eq(blog_post)
expected: #<InstanceDouble(BlogPost) (anonymous)> got: nil
(compared using ==)
![Page 75: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/75.jpg)
# app/controllers/blog_posts_controller.rb class BlogPostsController < ApplicationController ...
def create @blog_post = BlogPost.create(blog_post_params) end
... end
![Page 76: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/76.jpg)
# rspec spec/controllers/blog_posts_controller_spec.rb...
Finished in 0.03122 seconds (files took 1.52 seconds to load)3 examples, 0 failures
# rspec....
Finished in 0.17293 seconds (files took 1.49 seconds to load)4 examples, 0 failures
# rspec spec/features/creating_a_blog_post_spec.rb.
Finished in 0.15204 seconds (files took 1.42 seconds to load)1 example, 0 failures
![Page 77: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/77.jpg)
# spec/controllers/blog_posts_controller_spec.rb require 'rails_helper'
describe BlogPostsController do
...
describe '#create' do it 'creates a blog post record' do expect(BlogPost).to receive(:create).with(title: 'My Title', body: 'My Body') post :create, { blog_post: { title: 'My Title', body: 'My Body', } } end
it 'returns the new blog post to the view' do blog_post = instance_double(BlogPost) allow(BlogPost).to receive(:create).and_return(blog_post) post :create, { blog_post: { title: 'My Title', body: 'My Body', } } expect(assigns[:blog_post]).to eq(blog_post) end end end
![Page 78: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/78.jpg)
# spec/controllers/blog_posts_controller_spec.rb require 'rails_helper'
describe BlogPostsController do
...
describe '#create' do let(:post_params) { { blog_post: { title: 'My Title', body: 'My Body', } } }
it 'creates a blog post record' do expect(BlogPost).to receive(:create).with(title: 'My Title', body: 'My Body') post :create, post_params end
it 'returns the new blog post to the view' do blog_post = instance_double(BlogPost) allow(BlogPost).to receive(:create).and_return(blog_post) post :create, post_params expect(assigns[:blog_post]).to eq(blog_post) end end end
![Page 79: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/79.jpg)
# rspec....
Finished in 0.17293 seconds (files took 1.49 seconds to load)4 examples, 0 failures
![Page 80: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/80.jpg)
Imagine if testing the way you want to was second-
nature.
![Page 81: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/81.jpg)
TDD can help you get there.
…whether you end up embracing all of it or not.
![Page 82: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/82.jpg)
🤔 Questions?
![Page 83: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/83.jpg)
To Learn More
• learntdd.in/rails
• The RSpec Book
• Growing Object-Oriented Software, Guided By Tests
![Page 84: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/84.jpg)
Thanks! 🙃@CodingItWrong learntdd.in/rails
![Page 85: Getting Answers to Your Testing Questions](https://reader034.vdocuments.us/reader034/viewer/2022052606/588010e21a28ab421b8b6d6b/html5/thumbnails/85.jpg)