我目前正在研究一個Minitest擴展,其中包含Minitest::Runnable.run
with before/after_suite回調。 Minitest的工作方式是測試類從Minitest::Runnable
繼承。此外,describe
塊動態創建,從他們中定義的測試類繼承的類。所以動態定義類的子類方法,正確評估子類
# Minitest::Spec inherits from Minitest::Runnable
class TestClass < Minitest::Spec
describe 'a describe block' do
it 'should say hi' do
# test here
end
end
end
生成,從TestClass中,其name
是"a describe block"
繼承一個新的類。這將導致Minitest流水線不斷髮展,並且每個類別都會調用Mintest::Runnable.run
(例如,在每種情況下,self
都會變爲包括"a describe block"
在內的每個類別)。供參考:
module Minitest::Runnable
def self.run reporter, options = {}
require 'rubygems'; require 'pry'; binding.pry
filter = options[:filter] || '/./'
filter = Regexp.new $1 if filter =~ /\/(.*)\//
filtered_methods = self.runnable_methods.find_all { |m|
filter === m || filter === "#{self}##{m}"
}
with_info_handler reporter do
filtered_methods.each do |method_name|
run_one_method self, method_name, reporter
end
end
end
end
我擴展的設計允許你有一個before_suite
方法,它包裝MINITEST :: Runnable.run工作:
class TestClass < Minitest::Spec
before_suite do
# do something
end
describe 'a describe block' do
it 'should say hi' do
# test here
end
end
end
我找到了工作大多不過我正在遇到繼承問題。當我重新定義包裝器方法時,我的新單例方法的接收器即使對於子類(即使對於descibe塊)也是TestClass
。這會導致我的測試無法找到。
下面是我目前實施前套件:
module Minitest::SuiteCallbacks
def self.extended(base)
base.class_eval do
class << self
def before_suite(&before_suite_proc)
@before_suite_proc = before_suite_proc
context = self
original_singleton_run = method(:run)
define_singleton_method :run do |*args, &block|
# `self` here winds up being `TestClass` instead of the dynamic class
# (e.g. self.name => "TestClass" instead of "a describe block")
context.setup_before_suite
original_singleton_run.call(*args, &block)
end
end
end
end
end
end
這抓住當前實施run
和包裝它。問題是,當它從動態"a describe block"
子類的上下文中調用self
裏面的方法是TestClass
而不是動態類時。
對於我能做些什麼來解決這個問題有什麼想法?我的目標是能夠動態地包裝繼承鏈中的任何方法,並使其適用於所有子類。
在此先感謝!