【问题标题】:Rails model specs passing, Sidekiq spec failingRails 模型规范通过,Sidekiq 规范失败
【发布时间】:2014-10-09 12:17:04
【问题描述】:

我正在构建一个运行投票的 Rails (4.1.0) 应用程序。每个投票都有nn 席位的对决。这是我的模型:

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 =&gt; '/sidekiq' 以初始化 sidekiq 可视面板并访问 /sidekiq 以查看工作是否已交付并运行正确

标签: ruby-on-rails rspec sidekiq


【解决方案1】:

Sidekiq 与您的问题无关。您直接调用 perform 所以问题出在 rspec 和 activerecord 上。比如把代码从perform方法中拉出来,直接放到spec里面,应该还是会失败。

我怀疑这些实例已经过时,需要从数据库中 #reload'd 以获取在 #perform 中所做的更改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-18
    相关资源
    最近更新 更多