>
> On Aug 22, 2011, at 5:50 PM, Lenny Marks wrote:
>
>> 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
> 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
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.
>>
>> 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.
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
>>
>> So how would one simulate a NativeException if needed (i.e. you want to stub
>> methods on it)?
>>
>> -lenny
>>
>>
>>
>>
>>
>> _______________________________________________
>> rspec-users mailing list
>> [email protected]
>> http://rubyforge.org/mailman/listinfo/rspec-users
>
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users