2016-01-26 74 views
0

我有一個PlantTree作業調用PlantTree服務對象。我想測試這個工作,以確定它使用tree參數實例化PlantTree服務並調用call方法。如何使用MiniTest中的假冒測試硬編碼類

我對該服務的作用或結果不感興趣。它有自己的測試,我不想重複這些測試的工作。

# 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方法編碼。所以我不能僞造它並將其作爲依賴項傳入。有沒有一種方法可以在執行方法的一生中僞造它?喜歡的東西...

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 

我使用Rails的默認堆,它使用MINITEST。我知道這可以用Rspec來完成,但我只對MiniTest感興趣。如果無法僅使用MiniTest或默認的Rails堆棧執行此操作,則可以使用外部庫。

回答

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實例。這個模擬進一步證實了這個呼叫被稱爲。

+0

只是一個評論,'mock.expect(:call)'需要另一個參數,這是返回值。否則它是一個'ArgumentError'。 –

+0

哎呀,對不起 –

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'ed。

聲明:這可能不是100%的功能,但這應該是正確的想法,假設我已經正確地閱讀了OP的Q.

+1

感謝您的努力,但不幸的是,它是我追求的MiniTest語法。我見過很多如何在RSpec中執行此操作的示例,但我無法在MiniTest中找到任何內容。 –

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