Minitest规格:多个前/后块

时间:2013-03-18 17:00:36

标签: ruby testing minitest

这是我所处情况的最小通用例子:

测试/ 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测试文件中,因此始终执行常见的beforeend任务,但在这种情况下我还需要使用方法{{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块包含唯一被执行的块。

问题:如何实现这一目标并保持干燥?

2 个答案:

答案 0 :(得分:2)

由于MiniTest 3.3,before / end只是方法,而不是钩子,所以当你在do ...之前调用时,你会覆盖以前的方法。您可以使用的是MiniTest::TestCase.add_setup_hookhttp://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