这是我所处情况的最小通用例子:
测试/ mytest.rb
describe "What I want to test" do
include TestUtils
temporary_change_value(settings, :tmp_setting, value)
describe "test1 blablabla" do
# ...
end
describe "test2 blablabla" do
# ...
end
end
测试/支持/ test_utils.rb
module TestUtils
def self.included(base)
base.class_eval do
extend ClassMethods
before do
MyMainClass.interface = TestInterface.new
MyMainClass.handler.display.clear
end
after do
MyMainClass.handler.display.clear
end
end
end
module ClassMethods
def temporary_change_value(item, key, value)
old_value = nil
before do
old_value = item[key]
item[key] = value
end
after do
item[key] = old_value
end
end
end
end
TestUtils
模块包含在evey测试文件中,因此始终执行常见的before
和end
任务,但在这种情况下我还需要使用方法{{1} }作为此文件中所有测试的前块。这不起作用,似乎只有temporary_change_value
/ before
块中的一个被执行(特别是设置end
的那个)
我尝试过的事情
我试图改变MyMainClass.interface
/ before
块的顺序,就像这样。
end
仍然无法正常工作。现在describe "What I want to test" do
extend TestUtils::ClassMethods
temporary_change_value(settings, :tmp_setting, value)
include TestUtils
describe "test1 blablabla" do
# ...
end
describe "test2 blablabla" do
# ...
end
end
值不会被更改,因此它似乎是第二个settings
/ before
块包含唯一被执行的块。
问题:如何实现这一目标并保持干燥?
答案 0 :(得分:2)
由于MiniTest 3.3,before / end只是方法,而不是钩子,所以当你在do ...之前调用时,你会覆盖以前的方法。您可以使用的是MiniTest::TestCase.add_setup_hook
(http://bfts.rubyforge.org/minitest/MiniTest/Unit/TestCase.html#method-c-add_setup_hook)。您应该能够将temporary_change_value()
中的代码放在该特定测试用例的add_setup_hook
块中,以实现您正在寻找的内容。
答案 1 :(得分:1)
我终于设法解决了这个问题归功于Minitest宝石@zenspider的傻瓜。
<强>测试/ my_test.rb 强>
class TestWhatIWant < TestUtils::TestCase
temporary_change_value settings, :tmp_setting, value
describe "test1 blablabla" do
# ...
end
describe "test2 blablabla" do
# ...
end
end
<强>测试/支持/ test_utils.rb 强>
module TestUtils
module ClassUtils
def temporary_change_value item, key, value
mod = Module.new do
extend Minitest::Spec::DSL
before do
@old_value = item[key]
item[key] = value
end
after do
item[key] = @old_value
end
end
include mod
end
class TestCase < Minitest::Spec
extend TestUtils::ClassUtils
include TestUtils
def setup
Byebug.interface = TestInterface.new
Byebug.handler.display.clear
end
end
end
end