Test Exception with Rspec Rails - ruby-on-rails-3

I wanna do a test on a method call similar to:
call_to_method_1 param1
this method can raise for example:
raise msg1 if ...
raise msg2 if ...
My question is How to test exception with its msg1, msg2 exception messages wtih RSpec.

describe SomeClass do
let(:some_object) { described_class.new }
it 'should raise an exception' do
some_object.some_method('param').should raise_error(ExceptionClass, "exception_message")
end
end
if you raise "message" then the ExceptionClass will be instance of RuntimeClass.
IMO it's better to raise specific type of exception instead of relying on message though.

Related

How to throw this exception in a test?

I am trying to test a java.sql.SQLException handler which unwraps the exceptions like below. However I'm not sure how I would throw this exception in a test.
(-> e
(.getNextException)
(.getMessage)
(.startsWith "ERROR: duplicate key value"))
current mock (.getNextException) returns nil on this:
(throw (SQLException. "ERROR: duplicate key value"))
You want:
(throw (doto (SQLException. "Top-level exception")
(.setNextException (SQLException. "ERROR: duplicate key value"))))

How to write a test for Plug error handling

I'm trying to use Plug.Test to test error handling implemented with Plug.ErrorHandler -- with assert conn.status == 406 and alike.
I have the defp handle_errors (containing a single send_resp statement) and it seems to be called, however, my tests fail with the same exception still (as if handle_errors has no effect).
A reference to a sample advanced Plug (not Phoenix) app will also be appreciated.
Try something like this (not tested):
defmodule NotAcceptableError do
defexception plug_status: 406, message: "not_acceptable"
end
defmodule Router do
use Plug.Router
use Plug.ErrorHandler
plug :match
plug :dispatch
get "/hello" do
raise NotAcceptableError
send_resp(conn, 200, "world")
end
def handle_errors(conn, %{kind: _kind, reason: reason, stack: _stack}) do
send_resp(conn, conn.status, reason.message)
end
end
test "error" do
conn = conn(:get, "/hello")
assert_raise Plug.Conn.WrapperError, "** (NotAcceptableError not_acceptable)", fn ->
Router.call(conn, [])
end
assert_received {:plug_conn, :sent}
assert {406, _headers, "not_acceptable"} = sent_resp(conn)
end
Use assert_error_sent/2 to assert that you raised an error and it was wrapped and sent with a particular status. Match against its {status, headers, body} return value to assert the rest of the HTTP response met your expectations.
response = assert_error_sent 404, fn ->
get(build_conn(), "/users/not-found")
end
assert {404, [_h | _t], "Page not found"} = response

try and ignore errors in my tcl command

Hi I am new to tcl and I am trying to run a command in a for loop, while this command does what it needs to do, but, it throws an exception, which causes the loop to break. So, I need to ignore any error that is produced by this command and still try the command each time in my for loop.
for loop {
#do some stuff
$chassis exportPacketTrace $new_name -compress false 1 2 both #try this but ignore its error and continue
#do some stuff
}
Please help me with a good solution for this problem
if {[catch {$chassis exportPacketTrace $new_name -compress false 1 2 both} issue]} {
puts "There is a failure and it is ignored"
puts "Reason for failure : $issue"
}
Reference : catch

TCL, get full error message in catch command

#!/usr/bin/tclsh
proc test {} {
aaa
}
test
When I run this script I get error message:
invalid command name "aaa"
while executing
"aaa"
(procedure "test" line 2)
invoked from within
"test"
(file "./a.tcl" line 7)
If I run test command in catch I get only first line of error message.
#!/usr/bin/tclsh
proc test {} {
aaa
}
catch test msg
puts $msg
This prints:
invalid command name "aaa"
Is it possible to get full error message (file, line, procedure) in catch command? My program has many files and by getting just one line of error message it is difficult to find from where is it.
The short answer is to look at the value of errorInfo which will contain the stack trace.
The more complete answer is to look at the catch and the return manual pages and make use of the -optionsVarName parameter to the catch statement to collect the more detailed information provided. The return manual page gives some information on using this. But a rough example from an interactive session:
% proc a {} { catch {funky} err detail; return $detail }
% a
-code 1 -level 0 -errorstack {INNER {invokeStk1 funky} CALL a} -errorcode NONE -errorinfo {invalid command name "funky"
while executing
"funky"} -errorline 1
%
The detail variable is a dictionary, so use dict get $detail -errorinfo to get that particular item.

How to handle exceptions caused by nil:NilClass

I have a model called quiz, which has many questions models. I want to add some kind of esception handling so that when the user types in a wrong quiz_id in the URL, an error page would be rendered.
I wrote some helper methods in my QuestionsController to handle the exceptions:
private
def render_error(message)
#error_message = message
render 'error'
end
def active_quizzes_safe
active_quizzes = Quiz.active_quizzes(current_user.id)
render_error('Sorry! The request is invalid! Please log in again!') if active_quizzes.nil?
active_quizzes
end
def active_quiz_safe(quiz_id)
active_quiz = active_quizzes_safe.where(id: quiz_id).first
render_error('The quiz does not exist or you are not allowed to take this quiz!') if active_quiz.blank?
active_quiz
end
And here is the action in QuestionsController which has problems:
def show_quiz
if current_user
#quiz = active_quiz_safe(params[:quiz_id])
#questions = #quiz.questions
end
end
So if the :quiz_id in the URL localhost:3000/MY_URL/:quiz_id is not correct(that is, a record cannot be found), an error page should be rendered by the render_error mothod. However, when I tired a wrong :quiz_id, I got undefined method 'questions' for nil:NilClass. I guess this is because of the #questions = #quiz.questions in show_quiz method.
However, is the execution supposed to halt after the render_error action, which is before #questions = #quiz.questions? Why #questions = #quiz.questions is executed anyway?
In addtion, are there any standard ways to handle nil:NilClass errors like this?
Thank you!!
Look in your public/404.html, public/422.html and public/500.html files. Rails will automatically redirects if error occurs anyway. So I think you don't need to manually handle exceptions, except you have specific case. To test and view this error pages run application in production bundle exec rails s RAILS_ENV=production.
Calling render method does not halt the action. So you should carefully design your action to ensure that you return immediately after rendering. Like this:
def show_quiz
if current_user
active_quizzes = Quiz.active_quizzes(current_user.id)
if active_quizzes.nil?
render_error('Sorry! The request is invalid! Please log in again!')
else
#quiz = active_quizzes_safe.where(id: quiz_id).first
if #quiz.blank?
render_error('The quiz does not exist or you are not allowed to take this quiz!')
else
#questions = #quiz.questions
end
end
end
end
But in this case, I think it's better to use some exception control, like this:
def show_quiz
if current_user
active_quizzes = Quiz.active_quizzes(current_user.id)
#quiz = active_quizzes_safe.find(quiz_id)
#questions = #quiz.questions
end
rescue ActiveRecord::RecordNotFound
render_error 'The quiz does not exist or you are not allowed to take this quiz!'
end