#101 Testing with RSpec
10-15-2017

Summary

Using RSpec, learn how to create tests for your application and view your coverage.
12
rails test 13:04

Summary

Terminalrails generate rspec:install
rails g rspec:model user
rails g rspec:controller users
rails stats

# Run Tests
rspec

# Run tests of specific file and line
# where 20 is the line of spec that you want to run
rspec spec/models/user_spec.rb:20
Gemfilegroup :development, :test do
  ...
  gem 'rspec-rails'
end
gem 'simplecov', require: false, group: :test

# don't forget to add coverage to your .gitignore file
rails_helper.rbrequire 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = true
  config.infer_spec_type_from_file_location!
  config.filter_rails_from_backtrace!
end
spec_helper.rbrequire 'simplecov'
SimpleCov.start

RSpec.configure do |config|
  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end
  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = true
  end
  config.shared_context_metadata_behavior = :apply_to_host_groups
end
models/user_spec.rbrequire 'rails_helper'

RSpec.describe User, type: :model do
  context 'validation tests' do
    it 'ensures first name presence' do
      user = User.new(last_name: 'Last', email: '[email protected]').save
      expect(user).to eq(false)
    end
    
    it 'ensures last name presence' do
      user = User.new(first_name: 'First', email: '[email protected]').save
      expect(user).to eq(false)
    end
    
    it 'ensures email presence' do
      user = User.new(first_name: 'First', last_name: 'Last').save
      expect(user).to eq(false)
    end
    
    it 'should save successfully' do 
      user = User.new(first_name: 'First', last_name: 'Last', email: '[email protected]').save
      expect(user).to eq(true)
    end
  end

  context 'scope tests' do
    let (:params) { {first_name: 'First', last_name: 'Last', email: '[email protected]'} }
    before(:each) do
      User.new(params).save
      User.new(params).save
      User.new(params.merge(active: true)).save
      User.new(params.merge(active: false)).save
      User.new(params.merge(active: false)).save
    end

    it 'should return active users' do
      expect(User.active_users.size).to eq(3)
    end

    it 'should return inactive users' do
      expect(User.inactive_users.size).to eq(2)
    end
  end
end
controllers/users_controller_spec.rbrequire 'rails_helper'

RSpec.describe UsersController, type: :controller do
  context 'GET #index' do
    it 'returns a success response' do
      get :index
      expect(response).to be_success # response.success?
    end
  end

  context 'GET #show' do
    it 'returns a success response' do
      user = User.create!(first_name: 'First', last_name: 'Last', email: '[email protected]')
      get :show, params: { id: user.to_param }
      expect(response).to be_success
    end
  end
end



dancinglightning said 10 months ago:

Nice one.

Creating the models with factory_girl makes for much better reuse and smaller code.

And adding guard and autosave in the mix, the workflow has less steps and is much faster. 

kobaltz PRO said 10 months ago:

Agreed, will be covering both of those in upcoming episodes.

[email protected] said 10 months ago:

Hi @kobaltz, thank you so much for too much effort in make the videos as good as they are, can you create an episode for use mock and stubs?

kobaltz PRO said 10 months ago:

Hello. I plan on continuing the series with other parts of testing; Capybara, FactoryGirl, Mock, CI, CD, etc.

Login to Comment