0

サービス オブジェクトをPlantTree呼び出すジョブがあります。ジョブをテストして、引数を使用してサービスをPlantTreeインスタンス化し、メソッドを呼び出すことを確認したいと思います。PlantTreetreecall

私はサービスが何をするか、またはその結果には興味がありません。それには独自のテストがあり、仕事のためにそれらのテストを繰り返したくありません。

# app/jobs/plant_tree_job.rb
class PlantTreeJob < ActiveJob::Base
  def perform(tree)
    PlantTree.new(tree).call
  end
end

# app/services/plant_tree.rb
class PlantTree
  def initialize(tree)
    @tree = tree
  end

  def call
    # Do stuff that plants the tree
  end
end

ご覧のとおり、クラスはジョブPlantTreeのメソッドにハードコーディングされています。performしたがって、それを偽造して依存関係として渡すことはできません。perform メソッドの存続期間中、それを偽造する方法はありますか? 何かのようなもの...

class PlantTreeJobTest < ActiveJob::TestCase
  setup do
    @tree = create(:tree)
  end

  test "instantiates PlantTree service with `@tree` and calls `call`" do
    # Expectation 1: PlantTree will receive `new` with `@tree`
    # Expectation 2: PlatTree will receive `call`
    PlantTreeJob.perform_now(@tree)
    # Verify that expections 1 and 2 happened.
  end
end

MiniTest を使用する Rails のデフォルト スタックを使用しています。これは Rspec で実行できることは知っていますが、MiniTest にしか興味がありません。MiniTest のみ、またはデフォルトの Rails スタックでこれを行うことができない場合は、外部ライブラリを使用することにオープンです。

4

3 に答える 3

1

あなたは次のようなことができるはずです

mock= MiniTest::Mock.new
mock.expect(:call, some_return_value)
PlantTree.stub(:new, -> (t) { assert_equal(tree,t); mock) do
  PlantTreeJob.perform_now(@tree)
end
mock.verify

これは、PlantTree の新しいメソッドをスタブ化し、引数をツリーにチェックしてから、PlantTree インスタンスの代わりにモックを返します。そのモックは、呼び出しが呼び出されたことをさらに検証します。

于 2016-01-28T20:03:42.617 に答える
0

Minitest でこれを記述する方法がわかりませんが、モック (RSpec 構文はこちら) を使用できます。

expect(PlantTree).to receive(:new).with(tree)
expect_any_instance_of(PlantTree).to receive(:call)
# NOTE: either of the above mocks (which are expectations)
# will fail if more than 1 instance receives the method you've mocked -
# that is, PlantTree#new and PlantTree#call
# In RSpec, you can also write this using `receive_message_chain`:
# expect(PlantTree).to receive_message_chain(:new, :call)
job = PlantTreeJob.new(@tree)
job.perform

PlantTreeこのテストは、サービス オブジェクトが (1) を介してインスタンス化され#new、(2) が実行されない限り失敗します#call

免責事項: これは 100% 機能するわけではないかもしれませんが、OP の Q を正しく読んでいれば、これは正しい考えです。

于 2016-01-26T21:14:50.897 に答える
0
plant_tree_mock= MiniTest::Mock.new
dummy = Object.new
tree = Object.new
plant_tree_mock.expect(:call, dummy, [tree])

PlantTree.stub(:new, plant_tree_mock) do
  PlantTreeJob.perform_now(tree)
end

assert plant_tree_mock.verify
于 2017-08-17T23:59:21.737 に答える