3

いくつかのresqueワーカーと、これらのワーカーでジョブをキューに入れるアクションをテストしたいと思います。私はrspecとrailsを使用しています。

現在、Article.rbというモデルがあります。このモデルには、CategoriesSorterのジョブをキューに入れる必要があるかどうかをチェックするupdates_related_categoriesというbefore_saveメソッドがあります。その場合、記事が関連するカテゴリIDの引数を使用して、そのワーカーのジョブをキューに入れます。

ただし、テストでは、これらのジョブは、開発サーバーがジョブを送信するのと同じキューに送信されます。(root / redis /overviewでサーバーに接続できるresqueサーバーを使用して確認します)

私は知りたいです:

1)テストジョブを開発ジョブとは別のキューに送信するにはどうすればよいですか?

これが可能であれば、resqueのテストに関する他のアドバイスも歓迎します。

resque-unitとresque-specを示唆するいくつかの関連する質問を見ましたが、これらはかなり開発されておらず、有用な動作状態にすることができませんでした。また、Resque.inlineを使用することを聞いたことがありますが、resqueはテスト仕様では呼び出されないため、テストで作成されたオブジェクトの保存時に記事モデルから呼び出されるため、この場合に関連するかどうかはわかりません。

サンプルコード:

Article.rb:

 before_save :update_related_categories
 def update_related_categories
     #some if statements/checks to see if a related category needs updating
         Resque.enqueue(CategoriesWorker, [category_id])
     end
 end

カテゴリソート:

 class CategoriesSorter
     @queue=:sorting_queue
     def self.perform(ids)
        ids.each do |id|
           #some code
        end
      end
 end

仕様:

 it "should do something" do
     @article = #set something to enqueue a job
     @article.save
     #can i check if a job is enqueued? can i send this job NOT to the development queue but a different one?
 end
4

3 に答える 3

6

私が見ているように、ジョブをエンキューすると、performが呼び出されるかどうかをテストする必要はありません。Resqueが適切に実行することを信頼しています。ただし、1。update_related_categoriesを呼び出すとジョブがキューに入れられることをテストできます。次に、2。実行を呼び出すワーカーが目的の動作をもたらすかどうかを個別にテストできます。

一般的にResqueをテストする場合、resque-specとワーカーのシミュレーションを組み合わせることで、上記の2つの目標を達成できます。

1の場合、resque-specを使用すると、クラスでperformメソッドを呼び出すワーカーをシミュレートして、正しくキューに入れられていることを確認できます。

describe "Calling update_related_categories " do
  before(:each) do
    ResqueSpec.reset!
  end

  it "should enqueue the job" do
    Article.update_related_categories
    CategoriesSorter.should have_queue_size_of(1)
  end
end

2の場合、ジョブ(および開発キューとは別のキュー名を指定)、Resque :: Workerを作成してから、ワーカーをジョブに割り当てることができます。

def run_worker_simulation
  # see Resque::Job api for setting the args you want
  Resque::Job.create('test_queue_name', 'class_name', 'type', 'id')

  worker = Resque::Worker.new('test_queue_name')
  worker.very_verbose = true

  job = worker.reserve
  worker.perform(job)
end

それがあなたにいくつかのアイデアを与えることを願っています。

于 2012-12-03T18:51:18.527 に答える
1

resqueをテストするべきではありません。それは、resque開発チームの仕事です。アプリケーションは、perfomメソッドが実行する必要があることを実行することだけをテストする必要があります。モデルArticle.rbが必要に応じてジョブをエンキューすることをテストすることもできます。実際のジョブをresqueに送信することは無意味であり、テストは終了し、requeキューは無用なジョブでいっぱいになります。

次のようなことをします:

describe 'Article' do
  before(:each) do
    Resque.stub!(:enqueue)
  end

  it 'enqueues the job' do
    cat_id = 1
    Resque.should_receive(:enqueue).once.with(CategoriesWorker, [cat_id])
    Article.create(:category_id => cat_id)
  end
end

describe 'CategoriesSorter' do
  it 'sorts the categories' do
    result = CategoriesSorter.perform([1,4,6,3,2])
    result.should == [1,2,3,4,6]
  end
end

不要なメソッド/クラスのスタブまたはモック

編集:また、Articleをテストするときに、before(:each)フィルターをスタブresqueに設定して、仕様が実際のキューにジョブを送信しないようにすることをお勧めします。回答を編集しました。

于 2012-11-07T13:36:26.400 に答える
1

私は持っています

Resque.inline = ENV['RAILS_ENV'] == "test"

これにより、すべてのresqueタスクがテスト環境でインラインになります。

各ジョブクラスをテストするために、各ジョブの実行メソッドを個別にテストするための個別の仕様があります。

于 2012-12-03T18:56:01.077 に答える