-
-
Save jni-/11404310 to your computer and use it in GitHub Desktop.
| # inside app/models/person.rb | |
| class Person < ActiveRecord::Base | |
| validates :age, presence: true | |
| include PersonModel | |
| end | |
| # inside lib/domain/person_model.rb | |
| module PersonModel | |
| def legal_age? | |
| age > 18 | |
| end | |
| end | |
| # inside spec/lib/domain/person_model_spec.rb | |
| require 'rspec' | |
| require 'rspec_helper' | |
| describe 'PersonModel' | |
| let(:personModelStub) { Class.new { | |
| include PersonModel | |
| attr_accessor :age | |
| }} | |
| before(:each) do | |
| @person_model = personModelStub.new | |
| end | |
| it 'should ....' do | |
| # some test, you can use @person_model.legal_age? | |
| end | |
| end |
I wouldn't test Person using PersonModel. Instead, I'd test the business methods on PersonModel by stubbing/mocking the attribute readers/writers.
When I want to test Person, I'd stub/mock the methods on PersonModel.
Thanks @jbrains for your input!
The first concern is a pretty bad mistake on my end, I meant describe 'PersonModel'.
I too thought it would be annoying that, for each stub, I'd have to declare some attr_accessor's to mimic the active record fields. However, with time it turned out to be a really helpful documentation for the module. It clearly stated "this module needs this, this and this field/method to work". Whether or not these fields are provided by active record becomes irrelevant. Change to MongoDb and it still works!
The rule is : if it depends on an Active Record method (other than a magic field), then it goes with the AR class itself and it is tested as such. Otherwise, it goes in a module and it's unit tested.
Yes, that's the typical way to do it. Unfortunately,
PersonModelneeds to duplicate (and stub/mock) the magic attribute readers/writers that ActiveRecord would otherwise simulate. I don't see a way around that, and it causes a leaky abstraction/unhealthy dependency, wherePersonModelpractically depends (though theoretically doesn't have to depend) on the database schema.I tend to accept the risk.