Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RSpec + Rails Without rspec-rails @ RoRoSyd November 2015

D79fc498d7a5b2ce12180890247476f0?s=47 Jon Rowe
November 10, 2015

RSpec + Rails Without rspec-rails @ RoRoSyd November 2015


Jon Rowe

November 10, 2015

More Decks by Jon Rowe

Other Decks in Technology


  1. @JonRowe RSPEC + RAILS Without rspec-rails

  2. History 2179 commits, 194 people since 2009 Thin wrapper over

    Rails helpers
  3. Why Rails is integrated Rails is opinionated Rails is slow(er)

    to boot
  4. How Load components of Rails as needed Change how we

  5. How PORO Specs Model Specs Controller Specs Acceptance / Feature

    Specs Other Specs
  6. Autoloading To autoload or not to autoload. `require` works… but

    can be painful Rails constant lookup can be surprising
  7. require 'bundler/setup' gem_paths = Dir[ File.join Bundler.bundle_path, “/gems/**/lib” ] app_paths

    = Dir[ File.expand_path(‘./lib/**'), File.expand_path(‘./app/**') ] (gem_paths + app_paths).each do |path| ActiveSupport::Dependencies .autoload_paths << File.expand_path(path) end ActiveSupport::Dependencies.hook!
  8. PORO Specs Plain old Ruby specs No change!

  9. Model Specs Need to load the database beforehand Don’t use

    `describe Model`
  10. module Support::Database def self.setup! return true if defined?(@connection) require ‘yaml’;

    require ‘active_record' config = YAML.load(ERB.new( IO.read(‘config/database.yml') ).result) @connection = ActiveRecord::Base .establish_connection(config[‘test']) ActiveRecord::Base .raise_in_transactional_callbacks = true true end end RSpec.configuration.before :context, :db do Support::Database.setup! end
  11. RSpec.describe 'MyModel', :db do let(:models) do (1..6).map { |i| MyModel.create!

    hidden: false } end describe '.active' do it 'returns all active models' do models[0..2].each do |model| model.update_attributes! hidden: tru end expect( MyModel.active ).to match_array models[3..-1] end end end
  12. # For verified doubles with ActiveRecord ::RSpec::Mocks.configuration .when_declaring_verifying_double do |possible|

    target = possible.target if target.respond_to?(:define_attribute_methods) possible.target.define_attribute_methods end end
  13. Controller Specs Don’t

  14. Controller Specs

  15. Controller Specs Controller specs are already fullstack Too hard to

    isolate them Refactor logic to services and test or… Write acceptance tests
  16. Acceptance Specs Are still (as slow as) Rails Partition from

    your suite
  17. require 'capybara/dsl' RSpec.configure do |config| config.include Capybara::DSL, :app config.before :context,

    :app do unless Capybara.app require ‘config/environment.rb’ Capybara.app = Rails.application end Capybara.asset_host = "http://localhost:#{ENV['PORT'] || '8080'}" end config.after :example, :app do Capybara.reset_sessions! end end
  18. RSpec.describe 'Downloading a report', :app, :db do include Support::AdminHelper before

    do sign_in_as a_valid_admin end context 'when statistics are present' do it 'produces a csv' do visit "/admin" click_link 'Download CSV' expect { CSV.parse body }.to_not raise_error CSV::ParseError end end end
  19. RSpec.configure do |config| config.register_ordering :global do |examples| acceptance, unit =

    examples.partition do |ex| ex.metadata[:acceptance] end unit.shuffle + acceptance.shuffle end end
  20. Other Services / Presenters / Forms / ETC As long

    as they’re PORO(ish), work fine Mailers work with `email_spec`
  21. Other View / Request / Etc Not SRP, write acceptance

    specs or… Use `rspec-rails`

  23. CODE https://gist.github.com/JonRowe/867423bab8201b1f852b