2014-10-09 2 views
0

Я создаю приложение Rails (4.1.0), которое запускает опрос. каждый опрос имеет n Сопоставки с n Места. Вот мои модели:Спецификации модели Rails, оценка Sidekiq с ошибкой

class Matchup < ActiveRecord::Base 
    has_many :seats, dependent: :destroy 

    def winning_seat 
    seats.sort { |a,b| a.number_of_votes <=> b.number_of_votes }.last 
    end 
end 

class Seat < ActiveRecord::Base 
    belongs_to :matchup 

    validates :matchup, presence: true 
    validates :number_of_votes, presence: true 

    def declare_as_winner 
    self.is_winner = true 
    self.save 
    end 

end 

Мои спецификации для Matchup и Seat проходят без проблем. В конце опроса мне нужно отобразить победителя. Я использую работника Sidekiq для обработки конца опроса. Он делает много вещей, но вот код в вопросе:

class EndOfPollWorker 
    include Sidekiq::Worker 

def perform(poll_id) 
    poll = Poll.where(:id poll_id) 
    poll.matchups.each do |matchup| 
    # grab the winning seat 
    winning_seat = matchup.winning_seat 
    # declare it as a winner 
    winning_seat.declare_as_winner 
    end 
end 
end 

Спецификация для этого работника не проходит:

require 'rails_helper' 

describe 'EndOfPollWorker' do 
    before do 
    #this simple creates a matchup for each poll question and seat for every entry in the matchup 
    @poll = Poll.build_poll 
    end 

    context 'when the poll ends' do 
    before do 
     @winners = @poll.matchups.map { |matchup| matchup.seats.first } 
     @losers = @poll.matchups.map { |matchup| matchup.seats.last } 
     @winners.each do |seat| 
     seat.number_of_votes = 1 
     end 

     @poll.save! 

     @job = EndOfPollWorker.new 
    end 

    it 'it updates the winner of each matchup' do 
     @job.perform(@poll.id) 
     @winners.each do |seat| 
     expect(seat.is_winner?).to be(true) 
     end 
    end 

    it 'it does not update the loser of each matchup' do 
     @job.perform(@poll.id) 
     @losers.each do |seat| 
     expect(seat.is_winner?).to be(false) 
     end 
    end 

    end 

    end 
end 
end 

Когда я запускаю эту спецификацию, я получаю:

EndOfPollWorker when poll ends it updates the winner of each matchup 
    Failure/Error: expect(seat.is_winner?).to be(true) 

     expected true 
      got false 

Мои спецификации для моделей Seat и Matchup проходят отлично. Я вырезал много тестового кода, поэтому извините любые несоответствующие теги, предположим, что это не проблема!

Кроме того, когда рабочие фактически запускаются в режиме разработки, атрибут seat.is_winner фактически не обновляется.

Благодаря

+0

Sidekiq woker только принимает строковые параметры, вы уверены, что можете передать экземпляр этому woker? И вы начинаете какой-либо побочный woker? – dddd1919

+0

Вы правы! Я скопировал неправильно. Я обновлю код. Я пытался упростить, но я ввел ошибку. Я думаю, что @ job.perform начинает работать, не так ли? – panzhuli

+0

'@ job.perform' просто отправить работу в сторону sidekiq, тогда вам нужно запустить команду sidekiq в команде, например [bundle exec sidekiq] (http://sidekiq.org/), тогда эта работа будет выполнена. И работнику нужно несколько секунд, чтобы закончить его, чтобы вы могли «спать n», чтобы дождаться его. – dddd1919

ответ

0

Sidekiq не имеет ничего общего с вашей проблемой. Вы вызываете вызов напрямую, поэтому проблема связана с rspec и activerecord. Например, вытащите код из метода выполнения и поместите его непосредственно в спецификацию, он все равно должен потерпеть неудачу.

Я подозреваю, что экземпляры устарели и должны быть # reload'd из базы данных, чтобы получить изменения, сделанные в #perform.

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