JRuby 1.6.2
rspec-core (2.6.4)
rspec-expectations (2.6.0)
rspec-mocks (2.6.0)
rspec-rails (2.6.1)
I'm sure this has more to do with the way JRuby wraps Java exceptions
but I figured I'd post here in case anyone here has any insight or
pointers. In the context of writing a spec for a model like thing that
wraps legacy Java code, I found myself attempting to stub a method on a
Java Exception rescued in the implementation.
eg.
describe '#valid?' do
....
it 'adds validation exceptions raised by service to #errors' do
ve = ValidationException #a java exception
ve.stub(:localized_message).and_return('a bunch of errors')
service.stub(:validateTaskForSave).and_raise(ve)
subject.valid?
subject.errors.should == ['a bunch of errors']
end
the above example fails because the :localize_message stub is ignored
and instead the real implementation receives the message. I know this
typically screams typo but not in this case. Here is a more boiled down
version:
specify 'rescued exception message should be "bar" because I stubbed it'
do
begin
e = Java::java.lang.NullPointerException.new('foo')
e.stub(:message).and_return('bar')
raise e
rescue Java::java.lang.NullPointerException => e
e.message.should == 'bar'
end
end
Failure/Error: e.message.should == 'bar'
expected: "bar"
got: "foo" (using ==)
That seemed odd to me but maybe moot anyway since in reality I would be
need to rescue a NativeException masquerading as my target exception.
e.g. This code
def valid?
begin
service.validateTaskForSave(task)
rescue ValidationException => e
puts "rescued exception: #{e.class.name}"
.....
prints "rescued exception: NativeException" when hit through the
console.
So how would one simulate a NativeException if needed (i.e. you want to
stub methods on it)?
-lenny
on 2011-08-22 23:56
on 2011-08-23 19:36
it 'adds validation exceptions raised by service to #errors' do
ve = ValidationException #a java exception
ve.stub(:localized_message).and_return('a bunch of errors')
....
Just clarifying, but did you mean
ve = ValidationException.new
I tried replicating your spec but with java.lang.RuntimeException
instead of ValidationException and I got
exception class/object expected
because raise expects an instance of the exception, not the exception
class. Am I missing something?
Best,
Sidu.
http://c42.in
http://blog.sidu.in
on 2011-08-23 21:13
Please ignore my previous question - I just realised you're doing Java::java.lang.NullPointerException.new in your second example. I'm seeing the same behaviour and can't think of any way around it off the top of my head. You could try redefining Java::JavaLang::NullPointerException to be a Ruby RuntimeError within the scope of your spec but I'm not sure how this will work (if at all) when Java::JavaLang::NullPointerException is raised from native code. Best, Sidu. http://c42.in
on 2011-08-23 22:25
>> >> subject.valid? >> >> subject.errors.should == ['a bunch of errors'] >> end > I tried replicating your spec but with java.lang.RuntimeException > instead of ValidationException and I got > exception class/object expected > > because raise expects an instance of the exception, not the exception > class. Am I missing something? > > Best, > Sidu. > http://c42.in > http://blog.sidu.in You have to raise an exception instance, not the class of the exception as is typical with Ruby exceptions. Check out the "boiled down" example below to reproduce. >> end >> def valid? >> begin >> service.validateTaskForSave(task) >> rescue ValidationException => e >> puts "rescued exception: #{e.class.name}" >> ..... >> >> prints "rescued exception: NativeException" when hit through the console. The more I think about this, the more I wish it was different(more explicit) in JRuby. IMO, the above is very unintuitive (i.e. if I rescue a specific exception class then I would expect the exception instance to be an instance of that class). Any attempt to reference a custom method on a rescued java exception results in "undefined method". rescue MyJavaException => e # e.some_method "undefined method" e.cause.some_method # need to unwrap end AFAICT, the JRuby wiki makes no mention of this behavior ( https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby ). Of course that's more suited for the JRuby mailing list, but if it is just a matter of filling in the docs then there should still be an easy way to simulate such an exception with #and_raise such that custom methods on the exception can be stubbed. No?? -lenny
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.