Hi, I have a project that I had running under rspec 0.6.x and recently upgraded to 0.7.2. I am trying to isolate my controllers from the database as I go through and change all the specs to run under 0.7.2. I am having a problem where I need to make the create! method return the mocked object as well as raise RecordInvalid exception. Is this at all possible? I use the rescue statement in my controller methods and not @ object.new_record? or @object.valid? to check whether to redirect or render. -- controller -- def create @star = Star.create!(params[:star]) redirect_to star_path(@star) rescue ActiveRecord::RecordInvalid render :action => ''new'' end -- spec -- @star = mock(''star'') Star.should_receive(:create!).with({ ''name'' => nil }).and_return(@star) I''m new to all the mocking/stubbing business so my head spins are turning into headaches. :) Dylan. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20061122/9c0bfc6f/attachment.html
On 11/21/06, Dylan Egan <dylanegan at gmail.com> wrote:> Hi, > > I have a project that I had running under rspec 0.6.x and recently upgraded > to 0.7.2. > > I am trying to isolate my controllers from the database as I go through and > change all the specs to run under 0.7.2. > > I am having a problem where I need to make the create! method return the > mocked object as well as raise RecordInvalid exception. Is this at all > possible?AFAIK, Ruby won''t let you return an object and raise an error at the same time. You get one or the other.> I use the rescue statement in my controller methods and not @ > object.new_record? or @object.valid? to check whether to redirect or render. > > -- controller -- > > def create > @star = Star.create!(params[:star]) > redirect_to star_path(@star) > rescue ActiveRecord::RecordInvalid > render :action => ''new'' > end > > -- spec -- > @star = mock(''star'') > Star.should_receive(:create!).with({ ''name'' => nil }).and_return(@star)Hmmm. As I said above, I can''t imagine that Ruby will let you do that. What I would do in this case is this: -- spec -- @star = mock(''star'') Star.should_receive(:create!).with({ ''name'' => nil }).and_raise(ActiveRecord::RecordInvalid) Star.should_receive(:create).with({ ''name'' => nil }).and_return(@star) -- controller -- def create @star = Star.create!(params[:star]) redirect_to star_path(@star) rescue ActiveRecord::RecordInvalid @star = Star.create(params[:star]) render :action => ''new'' end OR def create @star = Star.create!(params[:star]) redirect_to star_path(@star) rescue ActiveRecord::RecordInvalid render :action => ''new'' end def new @star = Star.new end> I''m new to all the mocking/stubbing business so my head spins are turning > into headaches. :)Hope that helps. David> Dylan. > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > >
As far as your controller action goes, you might try switching from the exception handling way of rendering different actions to using something like: def create @star = Star.new(params[:star]) if @star.save redirect_to star_path(@star) else render :action => ''new'' end This keeps your @star object available even when it is invalid, which gives you the ability to use "error_messages_for ''star''" in your new.rhtml. It should also make specing easier. I basically cribbed it from scaffold_resource, so it''s also the core-team blessed way. I used to use the exception handling method, but because @star.save returns false on failure, there''s no reason to have other checks. It also gives you the ability to do more stuff to @star after it''s been initialized but before it has to be valid. Now I''m fully a convert to the @star.save conditional structure. Hope this helps. Chris On 11/22/06, David Chelimsky <dchelimsky at gmail.com> wrote:> On 11/21/06, Dylan Egan <dylanegan at gmail.com> wrote: > > Hi, > > > > I have a project that I had running under rspec 0.6.x and recently upgraded > > to 0.7.2. > > > > I am trying to isolate my controllers from the database as I go through and > > change all the specs to run under 0.7.2. > > > > I am having a problem where I need to make the create! method return the > > mocked object as well as raise RecordInvalid exception. Is this at all > > possible? > > AFAIK, Ruby won''t let you return an object and raise an error at the > same time. You get one or the other. > > > I use the rescue statement in my controller methods and not @ > > object.new_record? or @object.valid? to check whether to redirect or render. > > > > -- controller -- > > > > def create > > @star = Star.create!(params[:star]) > > redirect_to star_path(@star) > > rescue ActiveRecord::RecordInvalid > > render :action => ''new'' > > end > > > > -- spec -- > > @star = mock(''star'') > > Star.should_receive(:create!).with({ ''name'' => nil }).and_return(@star) > > Hmmm. As I said above, I can''t imagine that Ruby will let you do that. > What I would do in this case is this: > > -- spec -- > @star = mock(''star'') > Star.should_receive(:create!).with({ ''name'' => nil > }).and_raise(ActiveRecord::RecordInvalid) > Star.should_receive(:create).with({ ''name'' => nil }).and_return(@star) > > -- controller -- > > def create > @star = Star.create!(params[:star]) > redirect_to star_path(@star) > rescue ActiveRecord::RecordInvalid > @star = Star.create(params[:star]) > render :action => ''new'' > end > > OR > > def create > @star = Star.create!(params[:star]) > redirect_to star_path(@star) > rescue ActiveRecord::RecordInvalid > render :action => ''new'' > end > > def new > @star = Star.new > end > > > I''m new to all the mocking/stubbing business so my head spins are turning > > into headaches. :) > > Hope that helps. > > David > > > Dylan. > > > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > http://rubyforge.org/mailman/listinfo/rspec-users > > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-- Chris Anderson http://jchris.mfdz.com
Heya, Yeah I might just have to revert back to the way I used to do it. I liked the rescue way because it was a much tidier presentation. Also I have the new/create methods, just like anyone using REST and the .and_raise bit didn''t work. Or I could just use the DB on these cases. Choices choices. Thanks anyways. Dylan. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20061123/187606ab/attachment.html