I have an issue with testing error codes. If a record is not found, it raises exception ActiveRecord::RecordNotFound. The thing is, I wanna check if 404 is returned. If I go ahead and just check :
response.status.should == 404
Then this will make the test case fail as RecordNotFound exception is thrown and not caught. If I go ahead and say
expect {<call controller action>}.to raise_error(ActiveRecord::RecordNotFound)
and then check for the status code, then it will fail again, as this catches the exception and the response code is 200.
How should I test if 404 is returned in this kind of case ?
If you don't want checking the exceptions in other examples you can set the following options in your config/environments/test.rb:
config.consider_all_requests_local = false
config.action_dispatch.show_exceptions = true
I'm not sure I understand the specifics well enough to know if this will help you, but check out bypass_rescue as described at https://www.relishapp.com/rspec/rspec-rails/docs/controller-specs/bypass-rescue.
Related
So I recently pulled in the Rails best practices gem and it said I should use the current_user.find instead of doing it a different way. The issue is, this of course throws ActiveRecord::RecordNotFound when the current_user doesn't have the record. Now in my integration tests, I explicitly test that a user cannot access another users records. This causes the error to be thrown. The issue is, I want to handle this error since I expect it to be thrown. It's currently making my tests red. How can I get my tests to go green, while still testing that the error is thrown? Any help is clarification on best practices would be greatly appreciated! Thank you!
sidenote
As you can see, I'm attempting to use assert_raise. Which isn't catching the error of course... And assert_field_no_difference is just one of my helper methods..
Also, I've been searching for answers for a while now. Most people address how to handle it within the controller, in respect to render a page, or redirecting, but I haven't found anyone addressing how to handle it as expected behavior within a test.
my integration test
test "tries to edit resource not associated with user" do
login(#user)
assert_field_no_difference #resource, 'url' do
assert_raise ActiveRecord::RecordNotFound do
put community_resource_path(#resource), params: { community_resource: {
url: 'http://www.example.com'}}
end
end
end
error being thown as expected
Error:
Community::ResourcesFlowsTest#test_tries_to_edit_resource_not_associated_with_user:
ActiveRecord::RecordNotFound: Couldn't find Community::Resource with 'id'=1 [WHERE "community_resources"."user_id" = $1]
app/controllers/community/resources_controller.rb:106:in `set_allowable_access_resource'
test/integration/community/resources_flows_test.rb:110:in `block in <class:ResourcesFlowsTest>'
I have successfully added the exception_notifier to my rails app, and it is emailing a notification for all exceptions at the application level (which is exactly what I want). The only problem is that I need to have a few short lines of code ran whenever an exception is raised as well, and am certain that there is a way to add these lines of code onto the notifier. But despite reading the documentation found here: https://github.com/smartinez87/exception_notification I am still unclear what/where I should put things. Can someone please explain this a bit better for me. I am relatively new to ROR. I just need to add some additional code to run whenever the notifier is alerted to an exception.
This seems to be the correct link to the background notification:
Using a begin rescue should do the trick.
def method
sentence1
begin
sentence2
sentence3
rescue => e
ExceptionNotifier.notify_exception(e)
Sentence code1
return action
end
end
As explained here:
https://github.com/smartinez87/exception_notification#background-notifications
So as a shorthand: To do code before or after the notification is sended, but outside of the notification method you need to catch the exception in the method who raised it and work there.
But remember: Catching exceptions should be an exception. If you know what could go wrong, try to fix it, not to catch it.
In the production environment configuration I can't seem to find a configuration parameter to tell the server that when an ActiveRecord Class.find() throws an exception, that it should really be an exception. In development mode, it throws an ActiveRecord::RecordNotFound exception, but in production it rescues it and renders a 404. I seem to remember this being something you could turn on/off? I would rather not monkey patch the 404 which is the only solution I have seen so far.
The .find(id) method should be used whenever you want an exception to be thrown if the id cannot be found as described in the documentation. If you don't want an exception to be thrown, you should use .find_by_id(id).
https://github.com/rails/rails/blob/4-0-stable/activerecord/lib/active_record/railtie.rb#L26
adds a mapping
'ActiveRecord::RecordNotFound' => :not_found
asking action_dispatch to rescue 'ActiveRecord::RecordNotFound' with :not_found response.
Doing -
YourAppName::Application.config.action_dispatch.rescue_responses.delete('ActiveRecord::RecordNotFound')
in your initializer might get what you're expecting.
I created a webpage and a XML REST service.
0.
I would like to know how errors are handled in Rails (general).
1.
Let say that a controller does not exists and I would like to redirect a user to a default "Page not found" address (website) or show a default error status code (REST).
2.
What is a best practice for handling controller action errors e.g. when saving but a record is not saved or some param[] field does not exists or else. Usually I use rescue command and I repeat this in every create or update action (would be cool to have some kind of general error handling for that case).
Thank you!
Rails handles 404 and 500 errors out-of-the-box. In development mode you will see detailed error messages. However, in production Rails will use the 404.html and 500.html pages in the public directory.
If the route is not recognised, Rails will return a 404 error.
I generally don't handle errors at the controller level unless they are expected - so I don't wrap everything in begin...rescue. Rails will return the 500 error page if something fatal has occurred. If I expect a particular set of parameters I validate before proceeding and in this case have a redirection or return result to indicate the incomplete parameters.
I want to verify that an exception is being thrown in some function tests by calling get :methodname, :params. I had expected just making this call and then verifying the result is a 500 would be sufficient, but rails is failing the test as soon as the exception is reached in the get. While I figure I could go ahead and wrap the get in a rescue and verify the exception is thrown myself, and would hope there's a better method for doing this.
What's the best way to verify an exception is thrown when using a get in your tests?
You can do:
def test_sommat
assert_raises SomeException do
get :methodname, params
end
end