Simple one-liner tests for common Rails functionality
Go to file
Elliot Winkler 55f45d9549 Refactor AssociationMatcher to use new OptionVerifier
When using an association matcher you may have qualifiers on that
matcher which let you make assertions on options passed to the
association method that you are testing. For instance, has_many has a
:dependent option and so in order to test this you say something like

    it { should have_many(:people).dependent(:destroy) }

In order to test such an option we have to compare the option you passed
with what the actual value of that option is. This is usually obtained
by looking at the reflection object of the association in question,
although it can be obtained by other means too.

Anyway, the code that does this comparison isn't terrible, but there are
two problems with it. First, it involves typecasting both expected and
actual values. For instance, this:

    has_many :people, dependent: :destroy
    it { should have_many(:people).dependent(:destroy) }

should be equivalent to:

    has_many :people, dependent: :destroy
    it { should have_many(:people).dependent('destroy') }

should be equivalent to:

    has_many :people, dependent: 'destroy'
    it { should have_many(:people).dependent(:destroy) }

Second, we are a little screwed if the method of obtaining the actual
value of the option changes depending on which Rails version you're
using.

So, OptionVerifier attempts to address both of these issues. It's a
little crazy, but it works.

I also moved some methods from AssociationMatcher to ModelReflector
where they really belong.
2013-08-16 16:00:17 -06:00
features Remove 'assign_to' matcher 2013-04-03 13:08:27 -04:00
gemfiles Bump shoulda-context to ~>1.1.2 for Rails 4 compat 2013-08-16 15:32:08 -06:00
lib Refactor AssociationMatcher to use new OptionVerifier 2013-08-16 16:00:17 -06:00
spec Use `get` instead of `match` in routes 2013-08-16 16:00:17 -06:00
.gitignore Unignore Gemfile.lock, per Appraisal instructions. 2012-04-10 22:55:29 -04:00
.travis.yml Specify bundle install for travis. 2013-08-01 14:04:04 -04:00
Appraisals Add Rails 4 Appraisal 2013-08-16 15:32:06 -06:00
CONTRIBUTING.md Include step to update NEWS in contribution guidelines 2013-03-27 11:11:19 -04:00
Gemfile Bump shoulda-context to ~>1.1.2 for Rails 4 compat 2013-08-16 15:32:08 -06:00
Gemfile.lock Bump shoulda-context to ~>1.1.2 for Rails 4 compat 2013-08-16 15:32:08 -06:00
MIT-LICENSE Update copyright year to 2013 2013-02-22 10:46:22 -05:00
NEWS.md Bump to version 2.3.0 2013-08-16 13:05:00 -04:00
README.md removed permit example from ActionController Matchers since it was extracted 2013-08-10 16:40:31 -06:00
Rakefile Allow the suite to run sequentially via Appraisal, or one at a time with BUNDLE_GEMFILE set 2013-03-04 16:10:54 -05:00
shoulda-matchers.gemspec Add Rails 4 Appraisal 2013-08-16 15:32:06 -06:00

README.md

shoulda-matchers Gem Version Build Status

Official Documentation

Test::Unit- and RSpec-compatible one-liners that test common Rails functionality. These tests would otherwise be much longer, more complex, and error-prone.

Refer to the shoulda-context gem if you want to know more about using shoulda with Test::Unit.

ActiveRecord Matchers

Matchers to test associations:

describe Post do
  it { should belong_to(:user) }
  it { should have_many(:tags).through(:taggings) }
end

describe User do
  it { should have_many(:posts) }
end

ActiveModel Matchers

Matchers to test validations and mass assignments:

describe Post do
  it { should validate_uniqueness_of(:title) }
  it { should validate_uniqueness_of(:title).scoped_to(:user_id, :category_id) }
  it { should validate_presence_of(:body).with_message(/wtf/) }
  it { should validate_presence_of(:title) }
  it { should validate_numericality_of(:user_id) }
  it { should ensure_inclusion_of(:status).in_array(['draft', 'public']) }
end

describe User do
  it { should_not allow_value("blah").for(:email) }
  it { should allow_value("a@b.com").for(:email) }
  it { should ensure_inclusion_of(:age).in_range(1..100) }
  it { should_not allow_mass_assignment_of(:password) }
end

ActionController Matchers

Matchers to test common patterns:

describe PostsController, "#show" do
  context "for a fictional user" do
    before do
      get :show, :id => 1
    end

    it { should respond_with(:success) }
    it { should render_template(:show) }
    it { should_not set_the_flash }
    it { should rescue_from(ActiveRecord::RecordNotFound).with(:render_404) }
  end
end

Installation

In Rails 3 and Bundler, add the following to your Gemfile:

group :test do
  gem "shoulda-matchers"
end

# `rspec-rails` needs to be in the development group so that Rails generators work.
group :development, :test do
  gem "rspec-rails", "~> 2.12"
end

Shoulda will automatically include matchers into the appropriate example groups.

Credits

Shoulda is maintained and funded by thoughtbot. Thank you to all the contributors.

License

Shoulda is Copyright © 2006-2013 thoughtbot, inc. It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.