Search code examples
ruby-on-railsrubyrspecrspec-rails

rspec service objects how to test update_all


I can't understand, how to test this case. I googled it but didn't find anything. As a result (i think i am correct) I should expect to return 2 objects with new statuses false because I pass in subject.call id by first object what created in let. Please someone can help me and explain to me how to test update_all and other update cases. Thanks!

#rspec

describe Plans::MakeAllPlansInactive do
  subject do
    described_class.call(plan_id: plan.id)
  end

  let!(:plan) do
    create(:plan, active: true)
  end

  let!(:plan_1) do
    create(:plan, active: true)
  end

  let!(:plan_2) do
    create(:plan, active: true)
  end


  context 'when success' do
    it 'makes one active, other passive' do
      subject.to eq(2)
    end
  end

#service

def call
  return unless Plan.find(plan_id).active?

  update_our_plans
end

private

def update_our_plans
  Plan.where.not(id: plan_id).update_all(active: false)
end

Solution

  • For this service you obviously are more interested in the side-effect, than return value, so in spec describe what state you are expecting with a test like:

    it 'makes one active, other passive' do
      expect(Plan.count).to eq(3) # just to be sure
      expect{ subject }.to change{ plan_1.reload.active }.from(true).to(false).and(
        change{ plan_2.reload.active }.from(true).to(false)
      ).and(not_change{ plan.reload.active })
    end