I follow the TDD approach to creating our application and create a whole bunch of service objects, saving models strictly for data management.
Many of the services I created interact with models. Take, for example, MakePrintsForRunner:
class MakePrintsForRunner
def initialize(runner)
@runner = runner
end
def from_run_report(run_report)
run_report.photos.each do |photo|
Print.create(photo: photo, subject: @runner)
end
end
end
I appreciate that the create method can possibly be abstracted into the Print model, but keep it as it is for now.
Now, in the specification for MakePrintsForRunner, I really want to avoid using spec_helper, since I want my service specifications to be very fast.
Instead, I end the Print class as follows:
describe RunnerPhotos do
let(:runner) { double }
let(:photo_1) { double(id: 1) }
let(:photo_2) { double(id: 2) }
let(:run_report) { double(photos: [photo_1, photo_2]) }
before(:each) do
@service = RunnerPhotos.new(runner)
end
describe "#create_print_from_run_report(run_report)" do
before(:each) do
class Print; end
allow(Print).to receive(:create)
@service.create_print_from_run_report(run_report)
end
it "creates a print for every run report photo associating it with the runners" do
expect(Print).to have_received(:create).with(photo: photo_1, subject: runner)
expect(Print).to have_received(:create).with(photo: photo_2, subject: runner)
end
end
end
And everything goes green. Fine!
... Not so fast. When I run the entire test suite, depending on the order of the seeds, I now have problems.
, class Print; end print.rb (, , ActiveRecord) , , . :
NoMethodError:
undefined method 'reflect_on_association' for Print:Class
.
, . , , , . ?