使用 Minitest 时如何对几个不同的类方法进行存根或模拟调用?
比如我想测试一下这个方法:
def index
categories = CategoryAnalyzer.for_user(current_user)
@root_categories = categories.select { |c| c.parent_id.nil? }
@max_depth = CategoryAnalyzer.max_depth(categories)
@children_by_id = CategoryAnalyzer.children_by_id(categories)
end
请注意,它在
CategoryAnalyzer
上调用三个单独的类方法。有没有一种方法可以存根或模拟所有三种方法(for_user
、max_depth
和children_by_id
),并且不需要将对 stub
的一个调用嵌套在对 stub
的另一个调用的块中?
您可以使用
Minitest::Mock
类创建模拟对象并在其上存根不同的方法。
例如-
require 'minitest/autorun'
class UserProfileTest < Minitest::Test
def test_index_method
# Create a mock object
category_analyzer_mock = Minitest::Mock.new
# Stub the for_user method, for user categories
category_analyzer_mock.expect(:for_user, mocked_categories, [mocked_user])
# Stub the max_depth method
category_analyzer_mock.expect(:max_depth, mocked_max_depth, [mocked_categories])
# Replace the original MyCategories with the mock
MyCategories.stub(:new, category_analyzer_mock) do
#test code that calls index method
#you can call the method on an instance of your controller
controller = UserProfile.new
controller.index
# Assertions based on the expected behavior of your method
assert_equal expected_root_categories, controller.instance_variable_get(:@root_categories)
assert_equal expected_max_depth, controller.instance_variable_get(:@max_depth)
end
# Verify that the expected methods were called
category_analyzer_mock.verify
end
private
def mocked_user
#return a mocked user
end
def mocked_categories
#return mocked categories
end
def mocked_max_depth
#return mocked value
end
end