【发布时间】:2014-10-09 12:17:04
【问题描述】:
我正在构建一个运行投票的 Rails (4.1.0) 应用程序。每个投票都有n 与n 席位的对决。这是我的模型:
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 pass 的规格没有问题。在投票结束时,我需要显示获胜者。我正在使用 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 型号的规格都通过了。我删掉了很多测试代码,所以请原谅任何不匹配的标签,假设这不是问题!
此外,当工作人员实际在开发模式下运行时,seats.is_winner 属性实际上并没有更新。
谢谢
【问题讨论】:
-
Sidekiq Woker 只接受字符串参数,您确定可以将实例传递给该 Woker 吗?你开始任何sidekiq wker了吗?
-
你是对的!我复制不正确。我会更新代码。我试图简化,但我引入了一个错误。我认为@job.perform 启动了工人,对吧?
-
@job.perform只需将工作发送到sidekiq 队列,然后您需要像bundle exec sidekiq 这样在命令中启动一个sidekiq 工作人员,然后该工作将被执行。工人需要几秒钟才能完成它,所以你可以sleep n等待它。 -
感谢@dddd1919。我让它运行,但测试仍然失败。此外,当我运行应用程序本身时, is_winner 属性实际上并没有更新。我认为测试是正确的,但不知道如何解决问题。
-
认为您可以在您的 routes.rb 中执行
mount Sidekiq::Web => '/sidekiq'以初始化 sidekiq 可视面板并访问/sidekiq以查看工作是否已交付并运行正确
标签: ruby-on-rails rspec sidekiq