Zubin Henner
2008-Apr-15 22:05 UTC
[rspec-users] before_validation callbacks bypassed when stubbing :valid?
I''m testing an ActiveRecord model using rspec and mocha, and found that if I stub out the :valid? method, all before_validation callbacks are also skipped! Not ideal - I still want the callbacks to execute, but the validation to return true. Anyone know how to achieve this? class Item < ActiveRecord::Base before_validation :do_something def do_something raise "hell" end end Item.any_instance.stubs(:valid?).returns(true) item = Item.new item.valid? -- Posted via http://www.ruby-forum.com/.
Ashley Moran
2008-Apr-15 22:39 UTC
[rspec-users] before_validation callbacks bypassed when stubbing :valid?
On 15 Apr 2008, at 23:05, Zubin Henner wrote:> Item.any_instance.stubs(:valid?).returns(true) > item = Item.new > item.valid?Any reason why you are not using pure mocks here? I assume it''s not Item you are testing, but some other model that is associated with it? Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
Zubin Henner
2008-Apr-15 23:01 UTC
[rspec-users] before_validation callbacks bypassed when stubbing :vali
Ashley Moran wrote:> Any reason why you are not using pure mocks here? I assume it''s not > Item you are testing, but some other model that is associated with it?Hi Ashley, yes, you''re spot on - I''m using other associated models. I just simplified it for illustration. Here''s what I''m really testing: -- # order.rb has_one :freight_selection def calculate_freight_cost(freight_method) # ... (based on order total and freight method) end # freight_selection.rb belongs_to :order belongs_to :freight_method before_validation :set_freight_price def set_freight_price self.price = order.calculate_freight_cost(freight_method) end def validate # ... (confirms that freight_method is valid for order''s shipping address) end -- I don''t need to validate the freight selection since that''s handled elsewhere - I just want it to be valid. But I expected the before_validation filter to run. I''ve found a workaround, but I guess I''d like to understand this behaviour more, cause it had me stuck for a while. Is Mocha causing this or Rails? -- Posted via http://www.ruby-forum.com/.
Ashley Moran
2008-Apr-16 08:30 UTC
[rspec-users] before_validation callbacks bypassed when stubbing :vali
On 16 Apr 2008, at 00:01, Zubin Henner wrote:> I don''t need to validate the freight selection since that''s handled > elsewhere - I just want it to be valid. But I expected the > before_validation filter to run. I''ve found a workaround, but I guess > I''d like to understand this behaviour more, cause it had me stuck > for a > while. Is Mocha causing this or Rails?It''s simply because the :valid? method is what triggers the filter, and you are overriding it. (There''s nothing in the runtime sitting and watching for you to *send* the message, it''s handled when it''s *received*). I suggest you take one of two approaches: * If you are trying to build a suite of database-backed specs to prove the model layer works, then actually create a valid FreightSelection - whatever that entails. (Actually, better to use a story here, I think. * If you are trying to spec the Order class, then use a pure Mocha mock that stubs :id, :valid?, and whatever else ActiveRecord needs to keep it happy (look at rails_example_group.rb in the RSpec on Rails plugin for inspiration). This way you have full control over the second object. Hope this helps Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
Edvard Majakari
2008-Apr-16 11:34 UTC
[rspec-users] before_validation callbacks bypassed when stubbing :valid?
On Wed, Apr 16, 2008 at 1:05 AM, Zubin Henner <lists at ruby-forum.com> wrote:> I''m testing an ActiveRecord model using rspec and mocha, and found that > if I stub out the :valid? method, all before_validation callbacks are > also skipped!Naturally, as it is AR''s valid method which triggers those callbacks, and you just stubbed it. Not a straight answer to your question, but hopefully helpful nevertheless: you could consider implementing class method new_valid for each of your objects, so that whenever the concept of a valid object changes, there''s only one place you have to fix. However, as Ashley suggested, it might be that you''d rather want to resort to pure mock objects instead. -- "One day, when he was naughty, Mr Bunnsy looked over the hedge into Farmer Fred''s field and it was full of fresh green lettuces. Mr Bunnsy, however, was not full of lettuces. This did not seem fair." -- Terry Pratchett, Mr. Bunnsy Has An Adventure
Ashley Moran
2008-Apr-16 11:54 UTC
[rspec-users] before_validation callbacks bypassed when stubbing :valid?
On 16 Apr 2008, at 12:34, Edvard Majakari wrote:> you could consider implementing > class method new_valid for each of your objects, so that whenever the > concept of a valid object changes, there''s > only one place you have to fix.Or equally, you could have a Factory class that knows how to create valid objects. This can be handy for generating test data, and separates it from the class under test. (Some metaprogramming would let you define that in one class and still have it available as MyModel.new_valid.) Zubin - I am still leaning towards the mock approach though, unless you don''t have integration tests for your app, in which case having a model-layer test suite would add value. (But full-stack integration tests + model unit tests would be better). Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
Edvard Majakari
2008-Apr-16 13:10 UTC
[rspec-users] before_validation callbacks bypassed when stubbing :valid?
On Wed, Apr 16, 2008 at 2:54 PM, Ashley Moran <ashley.moran at patchspace.co.uk> wrote:> Or equally, you could have a Factory class that knows how to create > valid objects. This can be handy for generating test data, and > separates it from the class under test. (Some metaprogramming would > let you define that in one class and still have it available as > MyModel.new_valid.)Yep, that''s better. This is very similar to what I just recently did: I created a factory which creates pure stub objects for all more complex models I needed in tests. However, I mostly do just fine having all the stubs/mocks in the spec file concerned; that''s the approach I like the most, as then I have everything I need in a single file. -- "One day, when he was naughty, Mr Bunnsy looked over the hedge into Farmer Fred''s field and it was full of fresh green lettuces. Mr Bunnsy, however, was not full of lettuces. This did not seem fair." -- Terry Pratchett, Mr. Bunnsy Has An Adventure
Zubin Henner
2008-Apr-19 02:36 UTC
[rspec-users] before_validation callbacks bypassed when stubbing :vali
Ashley, Edvard: Thank you both for your advice and comments. For now, I''ve implemented fixture_replacement. Perhaps a story would be better, but this is working well for now. Cheers, Zubin -- Posted via http://www.ruby-forum.com/.