Rails 3 tutorial Ch. 10.6 ex 5 rspec failure
In solving exercise 5, I ran into a similar issue as this question. I refactored based on the answer given to that question but am still receiving the failure:
1) UsersController DELETE 'destroy' as an admin user should not self-destruct
Failure/Error: lambda do
count should have been changed by 0, but was changed by -1
# ./spec/controllers/users_controller_spec.rb:354:in `block (4 levels) in <top (required)>'
My spec:
it "should destroy the user" do
lambda do
delete :destroy, :id => @user
end.should change(User, :coun开发者_StackOverflowt).by(-1)
end
it "should redirect to the users page" do
delete :destroy, :id => @user
response.should redirect_to(users_path)
end
it "should not self-destruct" do
lambda do
delete :destroy, :id => @user.id
end.should change(User, :count).by(0)
end
and my controller:
def destroy
@user = User.find(params[:id])
if current_user == @user
flash[:notice] = "You cannot destroy yourself"
else
@user.destroy
flash[:success] = "User destroyed"
end
redirect_to users_path
end
I've checked the behavior in the browser and it works as expected. As always, any help is appreciated. Thanks!
The updated, working code:
describe "as an admin user" do
before(:each) do
@admin = Factory(:user, :email => "admin@example.com", :admin => "true")
test_sign_in(@admin)
end
it "should have links to destroy a user" do
get :index
response.should have_selector("a", :content => "delete" )
end
it "should destroy the user" do
lambda do
delete :destroy, :id => @user
end.should change{ User.count }.by(-1)
end
it "should redirect to the users page" do
delete :destroy, :id => @user
response.should redirect_to(users_path)
end
it "should not be allowed to delete itself" do
lambda do
delete :destroy, :id => @admin
end.should_not change{ User.count }
end
end
I just realised that I read the wrong one of the three tests you posted (it would be clearer if you only posted the failing test :)
However I'm confused, your "it should not self destruct"
test is exactly the same as "it should destroy the user"
:
it "should destroy the user" do
lambda do
delete :destroy, :id => @user
end.should change(User, :count).by(-1)
end
it "should not self-destruct" do
lambda do
delete :destroy, :id => @user.id
end.should change(User, :count).by(0)
end
You're running the same test both times but expecting different outcomes. I would take a look again at the "it should not self destruct" and see what you mean by that (I'm not sure).
I would guess that what needs to change is whatever is in the `change( xxxx ).by(0). What is it that shouldn't be changing through the test?
This bit me for a long time too. Try changing your syntax from:
should change(User, :count).by(-1)
to:
should change{ User.count }.by(-1)
Or try doing:
This is getting a little away from the book but you could try changing your syntax. The RSpec recommendation for this type of expectation is:
it "should destroy the user" do
expect{
delete :destroy, :id => @user
}.to change{ User.count }.by(-1)
end
Which I actually think is much cleaner and more readable anyway. Could you provide a link to the example as it is in the book?
精彩评论