2015-07-06 3 views
0

У меня проблема с тестированием одного из моих работников в приложении rails. Это выглядит следующим образом:any_instance не является экземпляром-агностиком

class UserStatisticsWorker 
    include Sidekiq::Worker 
    include Sidetiq::Schedulable 

    def perform(administration_id = nil) 
    administrations(administration_id).find_each do |administration| 
     User::StatisticsCalculator.new.recalculate_if_needed(administration.id) 
    end 
    end 

    private 

    def administrations(administration_id = nil) 
    administration_id.present? ? Administration.where(id: administration_id) : Administration.all 
    end 
end 

И тестируется с RSpec:

require 'spec_helper' 

describe UserStatisticsWorker do 

    describe 'perform' do 
    let!(:administration) { create(:administration) } 
    let!(:administration_2) { create(:administration) } 

    context 'when administration_id is present' do 
     it 'runs User::StatisticsCalculator for one administration' do 
     expect_any_instance_of(User::StatisticsCalculator).to receive(:recalculate_if_needed).once 

     subject.perform(administration.id) 
     end 
    end 

    context 'when administration_id is not present' do 
     it 'runs User::StatisticsCalculator for all administrations' do 
     expect_any_instance_of(User::StatisticsCalculator).to receive(:recalculate_if_needed).twice 

     subject.perform 
     end 
    end 
    end 
end 

Вторая спецификация не проходит с следующей ошибкой:

The message 'recalculate_if_needed' was received by #<User::StatisticsCalculator:85721520 > but has already been received by #<User::StatisticsCalculator:0x0000000a383498> 

Почему это?

ответ

1

A очень Хорошая практика заключается в том, чтобы избежать any_instance_of и вместо этого извлекать частные методы у вашего работника, который может быть более легко протестирован. Рефакторинг будет выглядеть примерно так:

class UserStatisticsWorker 
    include Sidekiq::Worker 
    include Sidetiq::Schedulable 

    def perform(administration_id = nil) 
    administrations(administration_id).find_each do |administration| 
     recalculate_if_needed(administration) 
    end 
    end 

    private 

    def recalculate_if_needed(administration) 
    User::StatisticsCalculator.new.recalculate_if_needed(administration.id) 
    end 

    def administrations(administration_id = nil) 
    administration_id.present? ? Administration.where(id: administration_id) : Administration.all 
    end 
end 

Затем проверить это следующим образом:

require 'spec_helper' 

describe UserStatisticsWorker do 

    describe 'perform' do 
    let!(:administration) { create(:administration) } 
    let!(:other_administration) { create(:administration) } 

    context 'when administration_id is present' do 
     it 'tries to recalculate for the specific administration' do 
     expect(subject).to receive(:recalculate_if_needed).once 

     subject.perform(administration.id) 
     end 
    end 

    context 'when administration_id is not present' do 
     it 'tries to recalculate for all administrations' do 
     expect(subject).to receive(:recalculate_if_needed).twice 

     subject.perform 
     end 
    end 
    end 
end 
1

Проблема заключается в том, что вы установили ожидания дважды случиться на экземпляре ... но что на самом деле происходит то, что он называется Once on two different instance.

т.е. это не ожидание того, что вы ищете ...

увидеть другой ответ на то, что вы могли бы попробовать вместо этого.

+1

hahahaha отличная ссылка :) –

Смежные вопросы