ActiveRecord::Base
has a big ol' API with multiple methods for both finding and saving objects. For example, your AR::B
objects might have been instantiated from a number of methods:
Foo.new(…)
Foo.create(…)
Foo.find(…)
Foo.find_by_sql(…)
Foo.find_[all_]by_*(…)
bar.foos
(associations)
Similarly, the object in question might get persisted by a few different methods:
foo.create
or foo.create!
foo.save
or foo.save!
foo.update_attributes
or foo.update_attributes!
Now, when writing unit tests, it's good practice to stub external method calls so that your test can focus on the business logic of the method in question. However, when it comes to working with AR::B
objects – for example in controller unit tests – it seems like you have to commit to one of the above methods, when actually as far as the business logic of the method is concerned it shouldn't be important which you choose.
Do you have to couple the behaviour of your method this tightly with its implementation or am I missing something simple?
One approach is to build your classes in such a way that you wrap up any ActiveRecord::Base
method calls in your own methods.
So instead of calling Foo.new(…)
directly...
class Foo < ActiveRecord::Base
def self.create_object(…)
new(…)
end
end
That way in your tests you can stub out your own methods instead of ActiveRecord's.
This approach (including its' benefits) is outlined in detail by Avdi Grimm in the book 'Objects On Rails'... http://objectsonrails.com
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With