Created
February 8, 2012 00:36
-
-
Save ches/1763572 to your computer and use it in GitHub Desktop.
RESTful controller spec examples
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This uses more real data and less mocking and stubbing for more direct and obvious code. | |
# It's probably easier to follow for people new to testing. | |
require 'spec_helper' | |
describe Notes::CommentsController do | |
let!(:commenter) { User.make! } | |
let!(:note) { Note.make! } | |
let(:comment) do | |
note.comments << Comment.make | |
note.comments.last | |
end | |
let!(:params) { { :note_id => note.id } } | |
let(:valid_attributes) { comment.attributes.slice *Comment.accessible_attributes } | |
let(:invalid_attributes) { { :body => nil } } | |
before(:each) { sign_in commenter } | |
shared_examples_for "any requested format" do | |
describe "GET edit" do | |
it "assigns the requested comment as @comment" do | |
get :edit, params.merge(:id => comment.id) | |
assigns(:comment).should eq(comment) | |
end | |
end | |
describe "POST create" do | |
context "with valid params" do | |
before(:each) { params.merge! :comment => valid_attributes } | |
it "creates a new Comment" do | |
expect { post :create, params }.to change {note.reload.comments.count}.by(1) | |
end | |
it "assigns a newly created comment as @comment" do | |
post :create, params | |
assigns(:comment).should be_a(Comment) | |
assigns(:comment).should be_persisted | |
end | |
it "sets current user as comment author" do | |
post :create, params | |
assigns(:comment).author.should eq(commenter) | |
end | |
end | |
context "with invalid params" do | |
before(:each) { params.merge! :comment => invalid_attributes } | |
it "does not create a new Comment" do | |
expect { post :create, params }.not_to change(note.comments, :count) | |
end | |
it "assigns a newly created but unsaved comment as @comment" do | |
post :create, params | |
assigns(:comment).should be_a_new(Comment) | |
end | |
end | |
end | |
describe "PUT update" do | |
context "with valid params" do | |
it "updates the requested comment" do | |
Comment.any_instance.should_receive(:update_attributes).with({'these' => 'params'}) | |
put :update, params.merge(:id => comment.id, :comment => {'these' => 'params'}) | |
end | |
it "assigns the requested comment as @comment" do | |
put :update, params.merge(:id => comment.id, :comment => valid_attributes) | |
assigns(:comment).should eq(comment) | |
end | |
end | |
context "with invalid params" do | |
before(:each) do | |
put :update, params.merge(:id => comment.id, :comment => invalid_attributes) | |
end | |
it "assigns the comment as @comment" do | |
assigns(:comment).should eq(comment) | |
end | |
end | |
end | |
describe "DELETE destroy" do | |
before(:each) { params.merge! :id => comment.id } | |
it "destroys the requested comment" do | |
expect { delete :destroy, params }.to change {note.reload.comments.count}.by(-1) | |
end | |
end | |
end | |
context "when HTML format requested" do | |
it_behaves_like "any requested format" | |
describe "GET show" do | |
it "returns 406 Not Acceptable" do | |
get :show, params.merge(:id => comment.id) | |
response.status.should be(406) | |
end | |
end | |
describe "POST create" do | |
context "with valid params" do | |
before(:each) { params.merge! :comment => valid_attributes } | |
it "redirects to the containing Note" do | |
post :create, params | |
response.should redirect_to user_note_path(note.owner, note) | |
end | |
it "sets flash message" do | |
post :create, params | |
flash[:notice].should match /comment has been added/i | |
end | |
end | |
end | |
describe "PUT update" do | |
context "with valid params" do | |
it "redirects to the containing Note" do | |
put :update, params.merge(:id => comment.id, :comment => valid_attributes) | |
response.should redirect_to [note.owner, note] | |
end | |
end | |
context "with invalid params" do | |
before(:each) do | |
put :update, params.merge(:id => comment.id, :comment => invalid_attributes) | |
end | |
it "re-renders the 'edit' template" do | |
response.should render_template(:action => 'edit') | |
end | |
end | |
end | |
describe "DELETE destroy" do | |
it "redirects to the containing Note" do | |
delete :destroy, params.merge(:id => comment.id) | |
response.should redirect_to [note.owner, note] | |
end | |
end | |
end | |
context "when JSON format requested" do | |
before(:each) { request.env["HTTP_ACCEPT"] = "application/json" } | |
it_behaves_like "any requested format" | |
describe "GET show" do | |
it "assigns the requested comment as @comment" do | |
get :show, params.merge(:id => comment.id) | |
assigns(:comment).should eq(comment) | |
end | |
end | |
describe "POST create" do | |
context "with valid params" do | |
it "returns 201 Created" do | |
post :create, params.merge(:comment => valid_attributes) | |
response.status.should be(201) | |
end | |
end | |
context "with invalid params" do | |
before(:each) { post :create, params.merge(:comment => invalid_attributes) } | |
it "returns 422 Unprocessable Entity" do | |
response.status.should be(422) | |
end | |
end | |
end | |
describe "PUT update" do | |
context "with valid params" do | |
it "returns 200 OK" do | |
put :update, params.merge(:id => comment.id, :comment => valid_attributes) | |
response.status.should be(200) | |
end | |
end | |
context "with invalid params" do | |
before(:each) do | |
put :update, params.merge(:id => comment.id, :comment => invalid_attributes) | |
end | |
it "returns 422 Unprocessable Entity" do | |
response.status.should be(422) | |
end | |
end | |
end | |
describe "DELETE destroy" do | |
it "returns 200 OK" do | |
delete :destroy, params.merge(:id => comment.id) | |
response.status.should be(200) | |
end | |
end | |
end | |
context "authentication" do | |
before(:each) do | |
sign_out commenter | |
request.env["HTTP_ACCEPT"] = "application/json" | |
end | |
it "is not required for GET show" do | |
get :show, params.merge(:id => comment.id) | |
response.should be_success | |
end | |
it "is required for volatile actions" do | |
put :update, params.merge(:id => comment.id, :comment => {}) | |
response.status.should be(401) | |
post :create, params.merge(:comment => {}) | |
response.status.should be(401) | |
delete :destroy, params.merge(:id => comment.id) | |
response.status.should be(401) | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This example uses heavier mocking/stubbing: more isolation of precisely what's | |
# being tested (and faster-running tests), but code is a bit harder to follow. | |
require 'spec_helper' | |
describe NotesController do | |
def mock_note(stubs={}) | |
@mock_note ||= mock_model(Note, stubs).as_null_object | |
end | |
let(:user) { User.make! } | |
before(:each) do | |
sign_in user | |
controller.stub(:current_user) { user } | |
end | |
describe "with a user browsing his own Notes" do | |
before(:each) do | |
User.stub(:find).with(user.to_param).and_return(user) | |
end | |
describe "GET index" do | |
it "assigns user's notes as @notes" do | |
user.stub_chain(:notes, :desc) { paginatable_array [mock_note] } | |
get :index, :user_id => user.to_param | |
assigns(:notes).should eq([mock_note]) | |
end | |
end | |
describe "GET show" do | |
it "assigns the requested note as @note" do | |
user.stub_chain(:notes, :find_by_slug).with("37") { mock_note } | |
get :show, :id => "37", :user_id => user.to_param | |
assigns(:note).should be(mock_note) | |
end | |
end | |
end | |
describe "with a user browsing another user's Notes" do | |
let(:browsed_user) { User.make! } | |
before(:each) do | |
User.stub(:find).with(browsed_user.to_param).and_return(browsed_user) | |
end | |
describe "GET index" do | |
it "assigns browsed user's notes as @notes" do | |
browsed_user.stub_chain(:notes, :desc) { paginatable_array [mock_note] } | |
get :index, :user_id => browsed_user.to_param | |
assigns(:notes).should eq([mock_note]) | |
end | |
end | |
describe "GET show" do | |
it "assigns the requested note as @note" do | |
browsed_user.stub_chain(:notes, :find_by_slug).with("37") { mock_note } | |
get :show, :id => "37", :user_id => browsed_user.to_param | |
assigns(:note).should be(mock_note) | |
end | |
end | |
end | |
describe "GET new" do | |
it "assigns a new note as @note" do | |
user.stub_chain(:notes, :build) { mock_note } | |
get :new, :user_id => user.to_param | |
assigns(:note).should be(mock_note) | |
end | |
end | |
describe "GET edit" do | |
it "assigns the requested note as @note" do | |
user.stub_chain(:notes, :find_by_slug).with("37") { mock_note } | |
get :edit, :id => "37", :user_id => user.to_param | |
assigns(:note).should be(mock_note) | |
end | |
end | |
describe "POST create" do | |
describe "with valid params" do | |
it "assigns a newly created note as @note" do | |
user.stub_chain(:notes, :build).with({'these' => 'params'}) { mock_note(:save => true) } | |
post :create, :note => {'these' => 'params'}, :user_id => user.to_param | |
assigns(:note).should be(mock_note) | |
end | |
it "redirects to the created note" do | |
user.stub_chain(:notes, :build) { mock_note(:save => true) } | |
post :create, :note => {}, :user_id => user.to_param | |
response.should redirect_to(user_note_url(user, mock_note)) | |
end | |
end | |
describe "with invalid params" do | |
it "assigns a newly created but unsaved note as @note" do | |
user.stub_chain(:notes, :build).with({'these' => 'params'}) { mock_note(:save => false) } | |
post :create, :note => {'these' => 'params'}, :user_id => user.to_param | |
assigns(:note).should be(mock_note) | |
end | |
it "re-renders the 'new' template" do | |
user.stub_chain(:notes, :build) { mock_note(:save => false) } | |
post :create, :note => {}, :user_id => user.to_param | |
response.should render_template(:action => "new") | |
end | |
end | |
end | |
describe "PUT update" do | |
describe "with valid params" do | |
it "updates the requested note" do | |
user.stub_chain(:notes, :find_by_slug).with("37") { mock_note } | |
mock_note.should_receive(:update_attributes).with({'these' => 'params'}) | |
put :update, :id => "37", :note => {'these' => 'params'}, :user_id => user.to_param | |
end | |
it "assigns the requested note as @note" do | |
user.stub_chain(:notes, :find_by_slug) { mock_note(:update_attributes => true) } | |
put :update, :id => "1", :user_id => user.to_param | |
assigns(:note).should be(mock_note) | |
end | |
it "redirects to the note" do | |
user.stub_chain(:notes, :find_by_slug) { mock_note(:update_attributes => true) } | |
put :update, :id => "1", :user_id => user.to_param | |
response.should redirect_to(user_note_url(user, mock_note)) | |
end | |
end | |
describe "with invalid params" do | |
it "assigns the note as @note" do | |
user.stub_chain(:notes, :find_by_slug) { mock_note(:update_attributes => false) } | |
put :update, :id => "1", :user_id => user.to_param | |
assigns(:note).should be(mock_note) | |
end | |
it "re-renders the 'edit' template" do | |
user.stub_chain(:notes, :find_by_slug) { mock_note(:update_attributes => false) } | |
put :update, :id => "1", :user_id => user.to_param | |
response.should render_template(:action => "edit") | |
end | |
end | |
end | |
describe "DELETE destroy" do | |
it "destroys the requested note" do | |
user.stub_chain(:notes, :find_by_slug).with("37") { mock_note } | |
mock_note.should_receive(:destroy) | |
delete :destroy, :id => "37", :user_id => user.to_param | |
end | |
it "redirects to the notes list" do | |
user.stub_chain(:notes, :find_by_slug) { mock_note } | |
delete :destroy, :id => "1", :user_id => user.to_param | |
response.should redirect_to(user_notes_url) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment