> 
> 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
>> rspec-users@rubyforge.org
>> http://rubyforge.org/mailman/listinfo/rspec-users
> 
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to