> > 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