ResourceSpec
Test your RESTful Rails controllers with ease.
Motivation
In every Rails app we have a set of controllers which encapsulates simple CRUD logic, especially in the admin area. Most of such controllers stays uncovered: it often seems excessive to test typical things. In other hand, in such typical places there always exists some unusual logic, which had to be tested. Furthermore, 100% test coverage rocks.
Simple Use Case
Given we have typical REST controller.
It can be tested with a few lines of code:
include_context "ResourceSpec", User do
it_behaves_like "GET :new"
it_behaves_like "POST :create"
it_behaves_like "GET :edit"
it_behaves_like "PUT :update"
it_behaves_like "DELETE :destroy"
it_behaves_like "GET :index"
end
FactoryGirl
factory for User
must be defined. Calls to FactoryGirl
or other factory engine can be overridden with settings.
Customization
Take a look at default settings. All of these settings can be changed inside include_context
block.
Some examples:
Redirect to #index
instead of #show
on create
Define override context somewhere in support
folder:
RSpec.shared_context "ResourceSpec overrides" do
let(:success_resource_url) { controller.url_for(action: :index) }
end
Then include:
include_context "ResourceSpec", User do
include_context "ResourceSpec overrides"
...
end
Nesting
This will make nested resources like /category/:category_id/groups
work:
let(:category) { create(:category) }
include_context "ResourceSpec", Group do
let(:base_url_args) { { category_id: category.id } }
...
end
Skipping passwords
POST :create
and PUT :update
examples are checking the record on compliance between params passed by request and record values saved to database. Some fields like images, generated tokens, encrypted passwords must be skipped.
include_context "ResourceSpec", User do
let(:not_expected_params) do
%i(password password_confirmation last_sign_in_at)
end
...
end
Timestamps
If you have any DateTime fields in your model - freeze the time:
around { |example| travel_to(Time.now, &example) }
If you have Date columns - use #to_date
in factory.
Additional action expectations
include_context "ResourceSpec", User do
it_behaves_like "GET :new" do
it "includes form tag" do
expect(response.body).to include("form")
end
end
...
end
XHR
include_context "ResourceSpec", User do
it_behaves_like "POST :create", xhr: true
it_behaves_like "PUT :update", xhr: true
it_behaves_like "DELETE :destroy", xhr: true
end
Paranoia on destroy
include_context "ResourceSpec", User do
it_behaves_like "DELETE :destroy", paranoid: true
end
Using shared example groups separately
Sometimes you do not need all the default flow in your spec. You can use just that expectations that you need. Here is the example from one of the real projects:
describe "updating collection" do
include_context "ResourceSpec", Collection
let(:resource) { controller.collection }
let(:instance) { create(:collection, :with_items, user: user }
it_behaves_like "PUT :update, success", xhr: true
describe "PUT :update, fail" do
let(:url_args) { invalid_update_url_args }
# Special case: model validations are external.
before { allow(controller.form).to receive(:save).and_return(false) }
include_examples "send PUT :update", xhr: true
include_examples "responds with failure", xhr: true
end
end
Take a look on shared examples we have.
Installation
Add this line to your application's Gemfile:
gem "resource_spec"
And this to spec_helper.rb
:
require "resource_spec/all"
And then execute:
$ bundle
Or install it yourself as:
$ gem install resource_spec
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/gzigzigzeo/resource_spec.