Disabling ActiveRecord Models in the Service Test

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

.

, . , , , . ?

+4
3

Print, :

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
      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

Edit

, ( Ruby?):

before(:all) do
  unless Object.constants.include?(:Print)
    class TempPrint; end
    Print = TempPrint
  end
end

after(:all) do
  if Object.constants.include?(:TempPrint)
    Object.send(:remove_const, :Print)
  end
end
0

, create , , Print, .

, , .

- , . MakePrintsForRunner, #from_run_report. - ? , , , .

, 1:

class MakePrintsForRunner
  def initialize(runner, printer)
    @runner = runner
    @printer = printer
  end

  def from_run_report(run_report)
    run_report.photos.each do |photo|
      @printer.print(photo: photo, subject: @runner)
    end
  end
end

, , @runner #print @printer. , @runner :

class MakePrints
  def initialize(printer)
    @printer = printer
  end

  def from_run_report(run_report)
    run_report.photos.each do |photo|
      @printer.print(photo)
    end
  end
end

MakePrintsForRunner MakePrints. . , , "".

, - , . . ​​

:

photo1 = double('photo')
photo2 = double('photo')
run_report = double('run report', photos: [photo1, photo2])
printer = double('printer')
action = MakePrints.new(printer)
allow(printer).to receive(:print)

action.from_run_report(run_report)

expect(printer).to have_received(:print).with(photo1)
expect(printer).to have_received(:print).with(photo2)

. , . , , .

#from_run_report, #from_photos, , . ( #print ).

, ? ActiveRecord. , , , . , , , , , - ActiveRecord.

0

- , stub_const a undefined .

before(:each) :

before(:each) do
  stub_const('Print', double(create: nil))
  @service.create_print_from_run_report(run_report)
end
0

Source: https://habr.com/ru/post/1526341/


All Articles